Edit 28th Feb: The URL to access the OData service is incorrect below, this bypasses the SMP server and goes directly to the OData service. The correct URL to use after registration is http[s]://<smpServer>:<port>/application.reverse.domain so in the case of this app the URL should be http://smpServer:8080/com.bluefinsolutions.poc.smp3.101 – you can also use the connection name in place of the app ID depending on the configuration which in this case would be http://smpServer:8080/SampleNorthwinds
When accessing the OData URL for the SMP server you must have a header value for X-SMP-APPCID equal to the registered appID in order to successfully access data.
—————————
This document aims to cover the minimum steps required to get a native iOS application functioning correctly through the SAP Mobility platform version 3.0 + and retrieving data from OData services. This document will focus on six main topics:
- Setting up your application on the SAP Mobility Platform Server
- Setting up an iOS application with the SMP libraries
- The code behind registering a device
- The code behind making a series of requests to retrieve data
- A basic UI to visualise it
- Running the app
SMP3 at time of writing is in ramp-up only. For more information on getting involved in the ramp-up please see this post Get your hands on SAP Mobile Platform 3.0.The complete source code (without SMP3 libraries or header files) can be found on my github page at bocallaghan/SMP3-101 · GitHub
Section 1 – Configuring SMP
Before you can connect any application to your SMP server you need to configure it to allow access. This is done covering 3 components:
- Re-using or creating a Security profile
- Defining your “endpoint” AKA the data source (in our case OData)
- Linking the two previous under a unique name called an “Application”
For the purposes of this document I won’t cover any of the SMP configuration in detail as that is more of a topic in itself however i will show enough to get you started. To logon to the administration centre of your SMP server go to https://<smpServerHostname>:8083/Admin using the admin passwords to logon (the user is usually smpAdmin).
Security profile
Go to the settings section and under “security profiles” add a new profile. When you have created the profile (and this should only be completed for DEMO’s or POC’s ONLY) add a hard coded username and password of the type “System Logon” specifying a username and password before saving.
Define your endpoint
Your endpoint is the data source your application will be able to access. In the same area as in the previous step go to the “Connections” tab. Here you can add a new “Back-end connection” by specifying a connection name, endpoint URL and a number of other settings which we will be leaving blank. For this example we will be using the Odata.org sample OData services found at http://services.odata.org/Northwind/Northwind.svc/
Create the application
Under the Applications area you can add a new application quite easily filling in an ID a name and the app type. So in my example the ID is com.bluefinsolutions.poc.smp3.101 (reverse domain name) and the name is “POC for SMP3”. Of course our type of app is native.
Next you need to link the app to the endpoint and the security profile. Under “Back-End” enter your connection details or select them from the list and then under “Authentication” choose the existing profile you created earlier.
And that is it – your server is now configured for your SMP3 application.
Section 2 – Setting up an iOS application with the SMP libraries
The first step of writing the app is to setup your Xcode project. For the purposes of this document a certain level of iOS development knowledge is required. However if there are any questions on steps I may have left out please do add a comment to this document and I will answer as soon as I can.
First open Xcode and create a new iOS project of the type “Empty Application”
Give the project a name – in my case it was SMP3-101
Once the project is created the first thing to do is to change the deployment target setting on the project to iOS 6.1
Next – select your target – in my case names SMP3-101 and under the build settings and under the architectures change the architectures to “Standard Architectures (armv7, armv7s)” note – not 64-bit. Also remove the 64-bit entry under the “valid architectures” entry.
Next we want to add our SMP3 library header files – these are the .h files that will have come with your SMP3 SDK installation. Create a folder in your project called “SMP3_Libraries”, right click and “Add Files”.
Now you need to add the “includes” folder from the iOS native SDK resources that came with the SMP SDK. The resources are found in the SDK install directory at “MobileSDK3\NativeSDK\ODataFramework\iOS\”.
Once these are in the next step is to add a number of pre-compiled libraries or .a files to your project. These files can be found in the libraries folder of the iOS native SDK resources that came with the SMP SDK. You will want all of the libraries in the folder “Debug-Universal” except for the libAfariaSLL.a file which has its functionality duplicated by the file “libcrypto.a”. You add these files by going back to the project level, click on your target “SMP3-101” and under “Build Phases” and “Link Binary with Libraries”. You also need to add a number of standard libraries from this list:
Once all libs are in you should see a list like this:
There is one final step in preparing your project to run and that is to tell Xcode where those header files for the libraries you just added are. They are in the project but still need to be pointed to. Going back to our target “SMP3-101” and under “Build Settings” and under the section “Search Paths” add the following path to the entry “Header Search Paths” – “$SRCROOT/SMP3-101/includes/public” which is recursive. Now you still need to make sure this path matches YOUR project but this is what has worked for me:
Now the fun starts – build your project and it should all be fine – if it is not then you have missed a step and please don’t continue until you fix it – these problems only get worse – not better!
Section 3 – The code behind registering a device
Now we need to add a new file to our project – and for the purposes of this POC we will call it the SMPController as a subclass of NSObject.
As you amy have guessed from the name this will be our controller for all comms with the SMP server. For anybody who is interested, the design pattern I will use here for convenience is to have this class do all the communications with the server and any front-end UI will simply register as a delegate for any high-level callbacks we will define.
Which brings us to the header of the file – SMPController.h This file has a number of variables such as server hostname, username and password (never normally hardcoded) and the name of the OData collection we are after. It will also define the methods that our UI can call to control the controller at a high level:
As i have deliberately commented the code in a very verbose way I will not go line for line but the highlights here are the two methods to be called from the UI – “initialiseSMP” to register our users and the second method is “beginDataRetrieval” which starts to get us data. There is also a “delegate” object which will be our reference to our UI class that is calling us so we can tell them our response to their queries.
(Again if this is seeming confusing I encourage you to download the code from bocallaghan/SMP3-101 · GitHub to read the comments better).
The implementation of the initialiseSMP method is one I will cover in detail:
Once the variables have been setup (username, password etc.) we create a connection object to represent our connection to SMP. For this single use application this is fine but in the future there is a connectionID created during every first connection that will need to be stored so the server can recognise you when you reconnect.
In this case we simple register our class as a delegate to be told if the registration is a success or failure and call the method “registerUser”.
Once the callbacks are triggered to give us the result we can tell the UI that it is safe to retrieve data:
You will see above there is a call to an “EncryptionManager” class to “resetEncryptionKey” – this works for a POC on a single connect basis but should be handled differently when dealing with a proper use-case (connect and reconnect rather than a new connection every time). Please see the documentation referenced at the end of this document for more details.
Section 4 – Making a series of requests to retrieve data
Now we have successfully registered our app we can request data from our OData service. There are three parts to our data request. First we need to retrieve what is called the “ServiceDocument” which tells us what is available. Once we have that we retrieve the “Metadata” which tells us the structure to expect our data in and then finally once we have that we can get our actual data.
The act of making a request is quite simple (especially when we are only getting data). The only thing that changes between the three calls is the URL and also what is known as a request tag. When you tag a request with a number (int) it allows you to identify which request it was when you receive the response. So for us tag 1 will be the serviceDocument , 2 the MetaData and 3 the data itself. So with that in mind the generic code for all the requests would be formed like this:
Note i have put this in a method that takes a different URL and tag for each call – nice and reusable.
For the three calls they are structured as follows:
The sequence in which these are executed is quite simple. Once one request returns successfully it triggers the next in the series. Our class is setup to receive callbacks for when requests succeed or fail. In our case, when a request succeeds, we pass the parsing of the response to a specific method and then call the next request down the chain. As follows:
Each request type has its only custom parsing method to extract and store the data we need. E.g. for the metadata we extract certain info which is different to the ServiceDoc etc.
Note that the parsing method of the actual data doesn’t trigger another request – instead it calls back to the UI passing the data received.
There is more to the controller class than I have mentioned here however please see the comments in-line for more information.
Section 5 – A basic UI to visualise it
The UI for this app will be very simple with only two buttons and a table of result data being shown.
First, create a new class with a XIB as a subclass of UIViewController implementing the UITableViewDataSource protocol:
The protocol “smpDelegate” has been defined in this project to map out the methods the SMPController class can callback to the UI and is structured as follows:
The two buttons on the UI (registration and Data download) should be hooked up to action methods and should call methods on the SMPController as shown below. In this class the variable self.controller is of the type SMPController and is created during the initialisation of the UI Class.
The protocol methods you will implement will control how the UI reacts to the SMP events – for example if the registration failed you may want to popup a message telling the user, or when the data download is complete you will want to refresh the results table. For this example I have followed this simple structure and it should be formed as follows:
And now the missing piece of the puzzle – how do we populate the table with data. As our view class is the data source of the table (Don’t forget to hook up the table to the class as its DataSource in the UI editor – control click on the table and drag to the orange icon marked “Files Owner” and select “DataSource”) we will need to structure the cells to be displayed as well as indicating how many cells there are in the table (a count of the number of results).
We do this as follows using the UITableViewDataSource protocol methods:
Now we are almost ready to run our app – the last piece of coding we need to do is to tell our app to load our UI – this is done in the AppDelegate file and just requires one extra line to add our UI to the window:
Section 6 – Run the app
Now we are ready to run the app. So launch the app and if you have no errors you should see a screen with our two buttons and an empty table as we have no data yet. I have coded my “Begin Data Download” button to not function until we have successfully registered.
Tap the “Register user” button and your console in Xcode should show you a log of everything that is happening on the SMP side. Eventually (assuming you have configured the server and app right” you should see “Successfully Registered User”. In that case my second button becomes ready for me to use.
Now I tap “Begin Data Download” and my console should once again start telling me what is happening and then assuming everything is configured right – I should see my table automatically update with data
You’re Done
And that is it – if you have come this far you have successfully created your first SMP3 app. As a quite simple POC this would be too simplistic for any real productive app however as a starting point it should be quite useful.
For more information about SMP 3 and the available APIs including how to use them please see the Sybase Infocenter at http://infocenter.sybase.com/
For more information on iOS coding I recommend using the website stackoverflow.com or searching for the Stanford lecture course CS193P which is a great starter on this topic.
Hello Brenton.
Thank you for the article.
I have done this example. User was registrated correctly. But when I download the data I receive the error “DBHelper class not loaded”. I attached the log file.
….
2014-03-12 19:01:08.590 SMP3-101[674:60b] Sucessfully registered user.
2014-03-12 19:01:09.902 SMP3-101[674:60b] Enabling offline…
2014-03-12 19:01:09.913 SMP3-101[674:4003] UrlString: http://services.odata.org
2014-03-12 19:01:09.914 SMP3-101[674:4003] Unable to instantiate Cache… Delta Link and CSRF (Offline) handling not possible
2014-03-12 19:01:09.918 SMP3-101[674:4003] DBHelper class not loaded
2014-03-12 19:01:09.920 SMP3-101[674:60b] Request Failed
…
Alexey,
I hit exactly the same problem using Xcode 4.6.2 and iOS 6.1 as you. Did you finally found a workaround? Thanks.
2014-04-18 13:35:46.814 SMP3-101[4280:19d03] Sucessfully registered user.
2014-04-18 13:36:00.808 SMP3-101[4280:19d03] Enabling offline…
2014-04-18 13:36:04.595 SMP3-101[4280:1b50b] Start queue…
2014-04-18 13:36:04.597 SMP3-101[4280:1b50b] DBHelper class not loaded
2014-04-18 13:36:55.965 SMP3-101[4280:1df03] UrlString: http://192.168.100.100:8080
2014-04-18 13:36:55.965 SMP3-101[4280:1df03] Unable to instantiate Cache… Delta Link and CSRF (Offline) handling not possible
2014-04-18 13:36:55.966 SMP3-101[4280:1df03] DBHelper class not loaded
2014-04-18 13:36:59.735 SMP3-101[4280:19d03] Request Failed
Hello Jian Gui.
We decided this problem.
You have to add flags to targets:
Targets > Build Settings > Other Linker Flags = “-ObjC -all_load”
Also you have to add all libraries to
Targets > Build Phases > Link Binary with Libraries
Best regards, Alexey.
Thank you, Alexey. It does work in my xcode as well.
I am not able to register. I have the server installed on a laptop and is running perfectly. When I tap on “Register User” I get this:
2014-06-24 17:04:36.102 SMP3-101[2850:60b] Initializing Client connection with ApplicationID : com.testApp Domain : default SecurityConfiguration: Generic_USER_PASS_auth
2014-06-24 17:04:36.105 SMP3-101[2850:60b] Setting Client connection with Host : 10.10.34.52, Port : 8080 Farm : (null) UrlSuffix : (null)
2014-06-24 17:04:36.105 SMP3-101[2850:60b] Setting Client connection with Url: http://10.10.34.52:8080
2014-06-24 17:04:36.105 SMP3-101[2850:60b] Assigning the selectors
2014-06-24 17:04:36.106 SMP3-101[2850:60b] Automatic Registration : Registering user ASYNCHRONOUSLY with user name : USER, security configuration : Generic_USER_PASS_auth
2014-06-24 17:04:36.107 SMP3-101[2850:3a0b] Got an IP address…
2014-06-24 17:04:37.238 SMP3-101[2850:3a0b] Could not resolve IP…
2014-06-24 17:04:37.239 SMP3-101[2850:3a0b] UrlString: http://10.10.34.52:8080
2014-06-24 17:04:37.239 SMP3-101[2850:3a0b] Unable to instantiate Cache… Delta Link and CSRF (Offline) handling not possible
2014-06-24 17:04:37.244 SMP3-101[2850:3a0b] UrlString: http://10.10.34.52:8080
2014-06-24 17:04:37.266 SMP3-101[2850:3a0b] UrlString: http://10.10.34.52:8080
Then the app crashes.
I checked the server logs and got this:
2014-06-24 17:04:32.936#ERROR#SMPApplicationSettingsHandler#null#Unauthorized
What’s wrong with the app?
Hi Benigno,
Sounds like there may be an Auth failure either between you and the SMP server or between the SMP server and your back-end system. Have you checked all those connections to make sure they are correct?
Also it mentioned “could not resolve IP” so make sure you have a valid route to host on all counts.
Otherwise maybe post some more info on your code and we can have a look.
Cheers,
Brenton.
Hi Brenton OCallaghan
Thanks for the blog,
In initialiseSMP method a static OdataURL (Which is directly pointing to the service) is used, instead of that we need to use the endpoint which is retrieved from SMPServer, this endpoint is used for requesting the service doc,metadata and further operations.
To get the endpoint :
Regards
Siva Chandu
Hi Siva,
That method is a nice addition – I hadn’t used the actual getApplicationEnpoint method before but it sounds both logical and useful 🙂 – I had updated the very top of the blog a few months ago with the more correct URL for a connection via SMP for the back-end data but this seems to be an even better way of doing it!
Thanks for your input,
Brenton.
Hi Brenton OCallaghan
I would like to add some more information on OData CRUD operations in the below link.
SMP 3.0 OData CRUD Operations in iOS Native
Regards
Siva Chandu.
Very useful information Siva – thanks for sharing!
Hi Brenton,
very nice article, thank you for share.
now i have a question, after i registered the fisrt time, i got 403 forbidden. even i have added [self.clientConn setApplicationConnectionID:@”myapplicationconnectionid”];
please check the screenshot bellow, do you have any ideas about that?
thanks in advance.
Billy
After configuring app in SMP 3 Admin cockpit make a “ping” to make sure that configurations are done correctly (ex. SMP 3 – Configuring Application in Management Cockpit). The credentials to login from app are the Backend credentials.
Midhun VP
thanks for your advice, i’ll take a look at your article. and i may misunderstand the register process. once i registered, got the application connection id, i shouldn’t register again, that’s why i got the 403 message, i should use the appconnid retrieve data directly. and it works for me for now.
thanks,
billy
Hi Billy,
Thanks for letting us know how you solved it and thanks Midhun VP for the suggestions 🙂
Cheers,
Brenton.
Hi Billy,
we do not understand the register process completely.
If we install the app and do the register process and retrieve the data everything is ok. But if we start the app new (without a new installation) we do not register the user again an set the connection id we get in the registration process:
[self.clientConn setApplicationConnectionID:[self readInPlistMitKey:@”appConnectionID”]];
and we set the encryptionKey in the manager and initialize the Cache once for the application lauch.
[EncryptionKeyManager setEncryptionKey:key withError:nil];
But if we want to retrieve the data we get a Request Failed.
Do you have some code snippeds for us what we have to do when we want to “reconnect to the smp” and retrieve the data without registration the user.
Thanks,
André
Hi André,
have you solved your problem, sorry for later reply. here are some codes , you may take a look if your problem still exsit.
Thanks Billy we use now the MAFLogonComponents. And so it works.
Best Regards,
André
Hi Andre,
can you share some information about MAFLogon. Im trying in SP05, and this method not working with https backend URL when we deploy it to server SP05.
Best Regards,
Sao Vu
Hello,
I have built the above example and also get the exception “Failed to register user”. Is it possible to help me out with this problem? The only other exception I can see in the log of xcode is ‘Unable to instantiate Cache… Delta Link and CSRF (Offline) handling not possible‘. But I don’t think it has anything to do with this exception.
On the SMP server I see the following error log:
2014-07-28 15:02:54.004#DEBUG#SMPApplicationSettingsHandler#null#Retrieve appHandler=[odata], application=[com.aegroup.demo.smp3] and backendURL=[/Connections].
2014-07-28 15:02:54.004#DEBUG#ApplicationConnectionHelper#null#Process application connection id.
2014-07-28 15:02:54.004#DEBUG#ApplicationConnectionHelper#null#Request Header ApplicationConnection ID=[null]
2014-07-28 15:02:54.004#DEBUG#ApplicationConnectionHelper#null#Generate UUID [f6ae6c3f-eae7-420c-bf93-d1c190425e9b] as application connection ID.
2014-07-28 15:02:54.004#ERROR#SMPApplicationSettingsHandler#null#Unauthorized
Is it possible to give me some directions for solving this problem?
Thanks in advance!
Best Regards
Carla
I was able to register the user when using the admin user.
BR
Carla
Hi Brenton OCallaghan
I am having a problem in offline native odata.
here is the link : SMP3 – AppDevelopment (native iOS Offline):
please help me in this.
Thanks & regards
Siva Chandu
Hi Brenton OCallaghan
when i start my application and press on register user so my application given me below issue.
[userManager registerUser:self.username password:self.password error:&error isSyncFlag:NO];
when i add isSyncFlag:NO]; its crashed.
or when i add isSyncFlag:YES]; its worked. but no data is came
kindly help me.
SIVA CHANDU
Regards
Ali
Hi Brenton, thanks you for your topic. It is really helpful !
But i have a question about register service on SAP. As i see in your topic, whenever i want to generate or retrieve Data from SAP, i must register first. But now, i just want to register only onetime, and when i close my app then re-open it , i want to retrieve it without register again.
I try by comment some line of code, but it does not work. i have to delete my register at SAP, then i register again to retrieve data, it is so inconvenient.
Thanks and regards
Sao Vu
Hi Brenton,
Veryhelpful topic.
Im able to register the device on SMP server.But when im retrieving the data im getting the following error.could please help me out .
2014-10-09 17:00:18.155 Testsmp3[5471:118283] Enabling offline…
2014-10-09 17:00:18.160 Testsmp3[5471:118425] Registering reachability notifier for: db41vv12.home
2014-10-09 17:00:18.162 Testsmp3[5471:118432] Start queue…
2014-10-09 17:00:18.162 Testsmp3[5471:118425] UrlString: http://db41vv12.home:8080
2014-10-09 17:00:18.163 Testsmp3[5471:118425] INTIALIZE CACHE
2014-10-09 17:00:18.173 Testsmp3[5471:118432] Error Domain=EncryptionKeyError Code=5001 “The operation couldn’t be completed. (EncryptionKeyError error 5001.)”
2014-10-09 17:00:18.176 Testsmp3[5471:118425] Cache Error –> Error Domain=CacheOperationError Code=1000 “Cannot create an NSPersistentStoreCoordinator with a nil model” UserInfo=0x79b5b950 {NSLocalizedDescription=Cannot create an NSPersistentStoreCoordinator with a nil model}
2014-10-09 17:00:18.176 Testsmp3[5471:118425] GET DELTA LINK
2014-10-09 17:00:18.177 Testsmp3[5471:118425] ERROR = Null or Empty encryption key passed
2014-10-09 17:00:18.178 Testsmp3[5471:118425] Error Domain=EncryptionKeyError Code=5001 “The operation couldn’t be completed. (EncryptionKeyError error 5001.)”
2014-10-09 17:00:18.179 Testsmp3[5471:118283] Request Failed
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Connectivity changed…
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Detected network…
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Start queue…
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Error Domain=EncryptionKeyError Code=5001 “The operation couldn’t be completed. (EncryptionKeyError error 5001.)”
Thnaks,
Praveen Kumar.
Hi Praveen,
Thanks for your comment – this looks like an interesting error and one I have not specifically seen before. I have a couple of questions:
1) Are you communicating with the server via a secure port rather than insecure?
– Initial error messages seem to be complaining about a lack of encryption keys which may point to your code expecting an insecure port e.g. 80 and the server expecting a secure connection e.g. 443
2) This reminds me of the old MBO approach which used to send a specific encryption key during the registration that you had to set during the data sync – perhaps check to see what settings are coming back as part of the registration.
Let me know if that helps at all,
Thanks,
Brenton.
Hi Brenton,
The below the response which im getting when im registering the device.Im using the port 8080.
“d:AndroidGcmPushEnabled” = false;
“d:AndroidGcmRegistrationId” = “”;
“d:AndroidGcmSenderId” = “”;
“d:ApnsDeviceToken” = “”;
“d:ApnsPushEnable” = false;
“d:ApplicationConnectionId” = “DEVICE NUMBER”;
“d:ApplicationVersion” = “1.0”;
“d:BlackberryBESListenerPort” = 0;
“d:BlackberryDevicePin” = “”;
“d:BlackberryListenerType” = 0;
“d:BlackberryPushAppID” = “”;
“d:BlackberryPushBaseURL” = “”;
“d:BlackberryPushEnabled” = false;
“d:BlackberryPushListenerPort” = 0;
“d:ConnectionLogLevel” = NONE;
“d:CustomCustom1” = “”;
“d:CustomCustom2” = “”;
“d:CustomCustom3” = “”;
“d:CustomCustom4” = “”;
“d:CustomizationBundleId” = “”;
“d:DeviceIMSI” = “”;
“d:DeviceModel” = “”;
“d:DevicePhoneNumber” = “”;
“d:DeviceSubType” = “”;
“d:DeviceType” = iPhone;
“d:ETag” = “2014-10-13 02:15:04.0”;
“d:MpnsChannelURI” = “”;
“d:MpnsPushEnable” = false;
“d:PasswordPolicyDefaultPasswordAllowed” = false;
“d:PasswordPolicyDigitRequired” = false;
“d:PasswordPolicyEnabled” = false;
“d:PasswordPolicyExpiresInNDays” = 0;
“d:PasswordPolicyLockTimeout” = 0;
“d:PasswordPolicyLowerRequired” = false;
“d:PasswordPolicyMinLength” = 8;
“d:PasswordPolicyMinUniqueChars” = 0;
“d:PasswordPolicyRetryLimit” = 20;
“d:PasswordPolicySpecialRequired” = false;
“d:PasswordPolicyUpperRequired” = false;
“d:ProxyApplicationEndpoint” = “http://serveripaddress:8000/appname“;
“d:ProxyPushEndpoint” = “http://serveripaddress:8080/Notification“;
“d:UploadLogs” = false;
“d:WnsChannelURI” = “”;
“d:WnsPushEnable” = false;
Thanks,
Praveen Kumar
Hi Praveen,
Thanks for the info. When you visit the app endpoint (http://serveripaddress:8000/appname) in your browser – are you getting a valid response or an error? I’m going to assume that is the point at which you app was failing earlier so there may be a problem with the response from that URL.
I’d recommend PostMan or some other similar tool which should allow you to test your connectivity and end-to-end data access to make sure the server is setup correctly.
Otherwise I would say check you code because it doesn’t look like you are using HTTPS/SSL for this connection so make sure you are not telling the code to use it.
Hope that helps,
Brenton.
Hi Brenton,
I tried to check the app endpoint (http://serveripaddress:8000/appname) through the AdvancedRest Client,Im getting the Response from the server.
Can please help me how to use HTTPS/SSL through xcode.Should i use any other class to establish a connection apart from SMPCLilentconnection class.
I have started the developing the SMP native application from the below reference.
Getting started with SMP3 Native OData iOS apps
Im done with the registration successfully,and hook up with getting the data from SMP server.
There is any sample code where it can be for my reference.
Thanks,
Praveen Kumar.
Hi Brenton,
Veryhelpful topic.
Im able to register the device on SMP server.But when im retrieving the data im getting the following error.could please help me out .
2014-10-09 17:00:18.155 Testsmp3[5471:118283] Enabling offline…
2014-10-09 17:00:18.160 Testsmp3[5471:118425] Registering reachability notifier for: db41vv12.home
2014-10-09 17:00:18.162 Testsmp3[5471:118432] Start queue…
2014-10-09 17:00:18.162 Testsmp3[5471:118425] UrlString: http://db41vv12.home:8080
2014-10-09 17:00:18.163 Testsmp3[5471:118425] INTIALIZE CACHE
2014-10-09 17:00:18.173 Testsmp3[5471:118432] Error Domain=EncryptionKeyError Code=5001 “The operation couldn’t be completed. (EncryptionKeyError error 5001.)”
2014-10-09 17:00:18.176 Testsmp3[5471:118425] Cache Error –> Error Domain=CacheOperationError Code=1000 “Cannot create an NSPersistentStoreCoordinator with a nil model” UserInfo=0x79b5b950 {NSLocalizedDescription=Cannot create an NSPersistentStoreCoordinator with a nil model}
2014-10-09 17:00:18.176 Testsmp3[5471:118425] GET DELTA LINK
2014-10-09 17:00:18.177 Testsmp3[5471:118425] ERROR = Null or Empty encryption key passed
2014-10-09 17:00:18.178 Testsmp3[5471:118425] Error Domain=EncryptionKeyError Code=5001 “The operation couldn’t be completed. (EncryptionKeyError error 5001.)”
2014-10-09 17:00:18.179 Testsmp3[5471:118283] Request Failed
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Connectivity changed…
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Detected network…
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Start queue…
2014-10-09 17:00:18.179 Testsmp3[5471:118425] Error Domain=EncryptionKeyError Code=5001 “The operation couldn’t be completed. (EncryptionKeyError error 5001.)”
Thnaks,
Praveen Kumar.
Very Good Lesson to start with iOS native development in SMP3.0
Hi Brenton,
Thank you for share, it is very nice article.
But, i have a question, i want to connect to HTTPS backend endpoint. But seem this app cannot connect to HTTPS, just HTTP backend. So, how can we connect to HTTPS? Because as i know, from SMP 3.0 SP04 , they change the backend URL from HTTP to HTTPS.
Thanks and Regards,
Sao Vu
Hi Brenton O’Callaghan,Kenichi Unnai
I’m able to register the device successfully, When I tap on the Begin Data Download button it getting issue like
And i debugged the code it’s only entering to the [self requestServiceDocument]; method , and going to handleReqFailed method and skipping [self requestMetadata]; [self requestData]; these methods.
And I’m getting response from REST client .
Thanks in advance,
VK.
Hi Midhun,
Midhun VP – SCN Member of the Month May 2014 Can i get the same sample app for Android.
Hi Rathish,
I think u should follow these blogs. They have iOS, WinPhone, and Android sample application and documents related.
Mobile Application Development Platform for Developers – Native Apps
Hope this help.
Regards,
Sao Vu.
I am going through the tutorial but I can’t get the Register User feature to work.
In the console I see the following:
2015-08-16 22:30:36.252 SMP3-101[5042:412558] Setting Client connection with Host : 172.16.108.133, Port : 8080 Farm : (null) UrlSuffix : (null)
2015-08-16 22:30:36.252 SMP3-101[5042:412558] Setting Client connection with Url: http://172.16.108.133:8080
2015-08-16 22:30:36.252 SMP3-101[5042:412558] Assigning the selectors
2015-08-16 22:30:36.254 SMP3-101[5042:412558] Automatic Registration : Registering user ASYNCHRONOUSLY with user name : odataUser, security configuration : Generic_USER_PASS_auth
2015-08-16 22:30:36.254 SMP3-101[5042:412558] Starting asynchronous request <Request: 0x7bb5d200>{name = ‘(null)’}
2015-08-16 22:30:36.255 SMP3-101[5042:413166] Got an IP address…
2015-08-16 22:30:36.287 SMP3-101[5042:413166] Could not resolve IP…
2015-08-16 22:30:36.288 SMP3-101[5042:413166] UrlString: http://172.16.108.133:8080
2015-08-16 22:30:36.288 SMP3-101[5042:413166] Unable to instantiate Cache… Delta Link and CSRF (Offline) handling not possible
I am able access the server from a browser with this URL:
http://172.16.108.133:8080/<appname> but I get a 403 error – Application connection id is not provided
I have the following code in the smpController.m file:
Any ideas why it is saying “Could not resolve IP…”?
I tried adding Targets > Build Settings > Other Linker Flags = “-ObjC -all_load” as suggested in a previous post but that caused the build to fail with Mach-o linker errors.
Thanks,
Dave
Hi David,
– I think you should check your privacy like firewall, i could not connect to SMP server because of firewall problem last time.
– If you want to access with URL: http:<server_address>/<appilcationid>, you should follow this tutorials: SMP 3.0 : REST API Application Development . You must access to http:<server_address>/odata/applications/latest/<applicationid> (details in the given link).
– You should try MAFLogon Library, it is really helpful lib to help us register and manage our connection. Mobile Application Development Platform for Developers – Native Apps
– I did try RequestBuilder as mentioned in this tutorials, it works with SMP 3.0 SP03, but with SP04 and higher, it will not work anymore. I have to use SODataOffline and SODataOnline to send/receive Odata to my server.
Hope this help,
Thanks and Best Regards,
Sao Vu.
Hi Sao, thank you for your response.
I have the firewall turned off on my Mac. I am running the SMP Server on a Windows 7 VM instance using VMWare Fusion. I’ve turned the firewall off on that as well. I can ping the server and I can access the server from the Safari browser on both the Mac and the iOS Simulator.
I’m not sure why I am getting a “Could not resolve IP” error. I will look into the other points you suggested and I will probably need to use the MAFLogon library (I am using SMP 3 SP07 SDK and SMP Server SP07) but my main concern right now is why the application cannot find the server.
Regards,
Dave
Hi Brenton,
I run the app in simulator and it keeps crashing. Few times (maybe 5% of the cases) it actually registers the users. After registration it crashes. When I restart the app, it gets the registration ID from the server and then it crashes. We are using SP5 PL0, I get an error: Unable to instantiate Cache… Delta Link and CSRF (Offline) handling not possible
Have you seen this?
Thanks for any idea.
Regards,
Tamas
I have the same exact issue. Can any experts here help?
Regards,
Adnan
Hi,
I am using Xcode 7 Swift project with SMP 3.0 SP 9.
Is there an updated version of this guide for Xcode 7?
I tried using a podspec to add the SDK to my project but I get an error:
I then tried to add the headers and libraries manually but I am presented with 100s of errors:
Any help will be appreciated.
Regards,
Jeff
Please open a new Discussion marked as a Question.
Regards, Mike (Moderator)
SAP Technology RIG
Please read the documentation in the Getting Started link at the top right to learn how to create a new Discussion marked as a Question. Despite the number of questions asked in Comments, unless directly asking for clarification, they should be asked in a Discussion.
Regards, Mike (Moderator)
SAP Technology RIG
Hi Michael,
Thanks for the info. First post, so I didn’t know the rules 🙂
Started a discussion.
Thanks!
No worries. We try to handle our new members gently. 😀