Wednesday, April 23, 2014

Make SMP iOS development easier with Cocoapods

I’ve been working quite some time with SAP Mobile Platform (SMP). As a developer I always hated to handle all the dependencies that comes with importing the iOS libraries into your project. When maintaining multiple projects with SMP Native SDK and multiple versions, this could be very hard to maintain. Each application has to import these libraries and setting the frameworks & library dependencies. 
Then I was thinking: “Why not using a dependency manager for this?”. iOS has a great dependency manager to handle this kind of stuff called Cocoapods ( ). I’ve been working with Cocoapods in some projects now and didn’t find anything about SMP Libraries so I figured it out.

How to use Cocoapods dependency manager for SAP Mobile libraries

To work with Cocoapods you need to install it first. Take a look at how to do this. Cocoapods depends on GIT ( ). I assume you already know how to work with GIT.

First lets create three GIT repositories:
  • SMPPods
This GIT repository will contain all the podspec files. A podspec is a specification of a pod.
  •  SMPLibraries
This GIT repository will contain all the library files for iOS SMP Native SDK and the header files for these libraries.

  • SMPModel
The SMPModel contains all the SMP Generated code for your project.

Take a look at the file structure for these three folders. I started with creating the SMPLibraries and SMPModel folders and pushed them to GIT. I also tagged the repositories, so it is easy to checkout a particular version. I tagged the SMPLibraries to “2.3.4” and the SMPModel to “1.0.0” and pushed these tags to the server. Now we are ready to create the podspecs. 

Creating the pod repository

To create a pod repository you need to have the following structure:


Take a look at the previous image. You can see it has the version number from the tag I pushed to GIT.

The SMPLibraries podspec

The SMPLibraries podspec imports the static library files (*.a files) as a resource. You can do this also with the vendored_libraries option, but this will add every file to the “LIBRARY_SEARCH_PATH” and this will give errors because we add Debug-iphoneos, Debug-iphonesimulator, Release-iphoneos and Release-iphonesimulator, which contain the same library names. We manually set the LIBRARY_SEARCH_PATH with these lines of config:

s.xcconfig  =  {
                 "HEADER_SEARCH_PATHS" => "$(PODS_ROOT)/SMPLibraries/includes/**",
        "OTHER_LDFLAGS" => "-lAfariaSLL -lclientrt -lcrypto -lDatavault -lMO -lPerformanceLib -lssl -lsupClientUtil -lSUPObj -lSUPSupportability -lsupUltralite"

We also have to link the static and dynamic libraries. This is done by the following lines of config:

s.frameworks = 'QuartzCore','MessageUI','CFNetwork','SystemConfiguration','Security','MobileCoreServices','Foundation','CoreGraphics','UIKit'
  s.libraries = 'z', 'stdc++.6.0.9', 'icucore.A'

The SMPModel podspec

The SMPModel podspec is just straightforward. Import the source code files. The last two lines of code are the most important ones.

s.requires_arc = false
s.dependency "SMPLibraries", "2.3.4"

This will tell cocoapods that this pod is not using ARC and that this pod depends on the SMPLibraries version 2.3.4.

Save the files and commit and push them to GIT.

Adding your private repo to Cocoapods 

After creating and pushing the SMPPods repository we can add this as an repo to your local Cocoapods installation. This is done by the following command:

Pod repo add <ALIAS> <GIT_URL>

As you can see in this image. The repo is added to the ~/.cocoapods

Using your Pods in your project

Now everything is ready we can test the pods and use them in our application. Therefor you need to do the following steps.

First create a project in XCode as you normally should do. Save it and close XCode again!

After you closed the XCode project go to the terminal. Go to the XCode project folder and type the command:

touch Podfile

This will create a empty file. Followed by the pod install command which will create a workspace and integrate the pods target into your project. As the result of the command says open your project from now on with the workspace!

After the install you should see that the pod install command has created a Pods directory in your project.

When you open the xcworkspace file. You will see that there is a Pods project in your workspace. We haven’t added any content to the Podfile (you see 0 targets). Lets add the SMPModel to this project.

In the terminal run the pod update command. The - -no-repo-update tag will prevent that the repository is updating again. This will make this command much quicker.

When you look at the project in XCode again you will see that the Pods now has three targets (pods, SMPLibraries, SMPModel) and we are ready to use the code from the pods!

To test the pods just import the MBOLogger and set the loglevel and run your application. You shouldn't see any warnings.

If you have multiple mobile applications using the same SMP Native SDK this is a good way to import them easy into each project. Just setup once and use it many times!

There was an issue with the resources. With this setting it will copy the lib files to the ipa which makes it 50+mb. If you replace the following lines this will be fixed:

s.subspec 'Debug-iphoneos' do |s_debug_iphoneos|
    s_debug_iphoneos.ios.vendored_library = "Libraries/Debug-iphoneos/*.{a}"
  s.subspec 'Debug-iphonesimulator' do |s_debug_iphonesim|
    s_debug_iphonesim.ios.vendored_library = "Libraries/Debug-iphonesimulator/*.{a}"
  s.subspec 'Release-iphoneos' do |s_release_iphoneos|
    s_release_iphoneos.ios.vendored_library = "Libraries/Release-iphoneos/*.{a}"
  s.subspec 'Release-iphonesimulator' do |s_release_iphonesim|
s_release_iphonesim.ios.vendored_library = "Libraries/Release-iphonesimulator/*.{a}"