November 27, 2015 | Written by: Dennis Schultz
Share this post:
More and more, the mobile market expects contextualized app content. Retail apps need to provide the user with the most up-to-date catalogs and promotions based on the shopping season, shopper’s location and store inventory. Financial institutions want to promote services best matched to the profile and banking history of individual customers. Governments want to make it easy to keep their citizens informed of current events and deal with emergencies.
But that contextual content puts a big burden on you as a developer. Business owners are coming to you with endless requests for content updates. You spend too much time on the tedious and error prone tasks of content maintenance. These changes tie up development resources that could be doing more valuable work elsewhere.
IBM Mobile Application Content Manager is a cloud-based content management system that empowers the business owner to build and maintain the content while you as a developer can build an app that simply consumes that content. This reduces the maintenance and release burden of the app and reduces the time it takes to get relevant content to the end user.
What you’ll need for this tutorial
- Apple Macintosh computer running Xcode (this tutorial has been tested with v7.1)
- Basic familiarity with iOS development
- A Bluemix ID
- Sample STARTER iOS app code from GitHub
The STARTER iOS app workspace contains a native Swift iOS app that displays a list of books. When a book in the list is tapped, an image of the book’s cover is displayed. In the starter version, the book data is hard coded in the view controller of the app. Through the course of this tutorial, you will modify the code to leverage the content services of IBM Mobile Application Content Manager (MACM) to retrieve book content from the service dynamically.
“But what if I’m developing something other than a native iOS app?”, you ask. In addition to the iOS SDK that will be explored in this article, there are actually three other methods to access MACM content from client applications:
Also be aware that the SDK for iOS native applications also includes a complete sample app similar to what you will end up with after finishing this tutorial.
Set up your environment
The STARTER iOS app is in a GitHub repository. To download, use the following command:
<code>git clone https://github.com/dschultz-mo/MACM-iOS-Tutorial-STARTER.git
This tutorial will have you adding code to connect to the MACM server and pull data from it. The code will be included in the body of this tutorial, but if you want to avoid some typing, you can install a few Code Snippets into your Xcode environment. To do so, copy the files from the provided directory into your Xcode environment.
- Close Xcode, if it is open
- Copy the provided code snippet files into your Xcode user data area using the following command:
<code>cp MACM-iOS-Tutorial-STARTER/snippets/* ~/Library/Developer/Xcode/UserData/CodeSnippets/
- Start Xcode by opening the CAAS.workspace file in MACM-iOS-Tutorial-STARTER/. You must open the workspace, not just the individual project. If you do, you will have compilation errors later.
Run the original Books app
The Books app will run on iPad or iPhone and should run on most versions of iOS. It can run on either a physical device or a simulated device. The device or simulator must be able to access internet addresses in order to contact the MACM server you will be creating.
NOTE that there currently is a bug in the app that causes the book list to be hidden if the app starts up in portrait orientation on an iPad. If this occurs, simply rotate the device to landscape and tap on a book. You can then rotate back to portrait mode.
- Open the workspace in Xcode if it isn’t already open.
- Run the CAASExample app on your device or simulator. The main interface of the app consists of a table view on the left that contains a list of books. As you click on books in the list, the book’s cover is shown in the view area on the right.
- Let’s look at what’s going on in the app. In the Xcode Navigator, open CAASExample/Books/BooksViewController.swift and scroll down to the function getBooks. As you can see the books in the list are simply created with hard coded data within the code of the app.
- If you need to add another book, you must come into the code, edit it, retest the app and redeploy it. See for yourself. Add the following code below the entry for Red October.
Re-run the app.
So here’s the problem… every time the business owners want to add a new book to the list, they have to call up development to make the change. You need to separate the dynamic content from the functionality of the app so that a content owner can update content without involving you. That’s exactly what IBM Mobile Application Content Manager does. Content is developed and managed by content experts (Marketing, Line of Business, Planners, etc.) through a web-based dashboard. The mobile app then uses SDKs to pick up that content dynamically – with no code changes.
Create a MACM service on Bluemix
IBM Mobile Application Content Manager is delivered as a service on the IBM Bluemix cloud. To create a MACM service, you must first have a Bluemix account. If you don’t yet have one, go to http://bluemix.net and click
SIGN UP in the upper right corner.
- To create your MACM service, follow the instructions https://ibm.biz/BluemixMACMDocs. Go ahead and create your service now.
- When you have created your service, click
LAUNCH to open the console as a content author.
This blog post is going to focus on accessing managed content from an iOS mobile app, but it will help to know the basics of how the content is created and managed in the console. For more details on using the MACM console, see https://ibm.biz/MACMKnowledgeCenter.
- The tiles on the dashboard each represent a Library. Libraries enable content owners to partition their content. For this tutorial, you will be looking at the Samples library which contains several content items, all of which are of the Content Type Book. Click on Samples to open the library.
- Each Content Item conforms to its specified template or Content Type. Click on “Adventures of Huckleberry Finn”. Notice the properties and attributes associated with each book.
- Leave this page open in your browser. You will come back to it in a few minutes.
Add the CAASObjC SDK to the Xcode workspace
In order to start using MACM, you need to include the SDK into your workspace. To install the CAASObjC SDK into an existing app, add the line
pod 'CAASObjC', :git => 'https://github.com/digexp/MACM-SDK-iOS.git' to your Podfile. If you want to use CAASObjC in a Swift application you must also add the line
- Close Xcode.
- Edit your Podfile. It should look like this:
- From a terminal opened to the MACM-iOS-Tutorial-STARTER folder, enter the command
pod install. Cocoapods will take care of installing the CAASObjC library and any dependencies it needs.
- Open the workspace in Xcode again. Now the SDK is available for you to code against.
Replace app hard coded data with CAAS SDK calls
There are basically two things you need to do in the app in order to start pulling content from MACM:
- Connect to the server
- Pull content items
Connect to the server
- Open CAASExample/CAASExample/AppDelegate. The code changes you need to make are marked with //TODO: markers. The simplest way to navigate around is to use the Jump Bar. Once you have a file open, click on the rightmost item in the breadcrumb in the banner above the editor. You can then select a TODO marker in the list to be taken directly to it.
Go to the first TODO and uncomment the import for CAASObjC.
- Force a build by pressing Command-B. If your build didn’t succeed, you either opened the project instead of the workspace or you didn’t get the pod installed correctly.
- Go to the next TODO and uncomment the declaration of caasService. The CaasService is the central service you use to get access to the MACM server. It is declared as a global variable so it is visible to all view controllers and supporting files.
Go to the final TODO. It is at this point in the
didFinishLaunchingWithOptions function that you want to insert the code to connect to your MACM server. If you installed the Code Snippets like I suggested, just click below the TODO and start typing “TUTORIAL CAAS Connect”. Content assist will offer to insert the snippet for you. The following code is added:
Let’s break this down a little.
CAASNetworkActivityIndicatorManager manages the network activity indicator and listens to all requests coming from the CAASService.
caasService you declared earlier is initialized here. The service takes five arguments which must correspond to the Bluemix service you created earlier. You will customize these in the next step.
- The app then tests to make sure the connection succeeded.
- Customize the baseURL, contextRoot, tenant, username and password values with the values you were given when you created the service. You can find this information on the Mobile Application Content Manager Bluemix dashboard.
- baseURL – This is the base portion of the URL labeled Published content on the dashboard. It will be something like
- contextRoot – This is the next segment of the Published content URL. It will be
- tenant – This is the final segment of the Published content URL. In the image below, it is
- username – Use the value for API ID
- password – Use the value for API password
Retrieve books data
Now that you have a connection to the server, you can implement the retrieval of dynamic content data. There are two places in the Books app where this is done.
Books View Controller
- Open CAASExample/Books/BooksViewController.swift.
- Navigate to the first TODO and uncomment the
import CAASObjC statement. (Note that you may need to scroll up in the Jump Menu to see it).
- Navigate to the second TODO and uncomment the
caasService.cancelAllPendingRequests() statement in the refresh procedure. This will cause all pending requests to the service to be cancelled if the user refreshes the screen. It just prevents bad things from happening if a refresh is requested before a previous request finishes.
- Navigate to the last TODO which takes you back to the
getBooks function you saw earlier. This is where the book inventory is currently hard coded. This is where things will get interesting. You will replace this getBooks routine with a new one that pulls content from MACM.
- Delete the function getBooks.
- Use the snippet TUTORIALgetBooks to insert the following code:
Again, the breakdown:
- An instance of
CAASContentItemsRequest is created which will fetch contents from the given contentPath.
completionBlock executes when the content arrives asynchronously and calls the local procedure
processReturnData. More on that in a moment.
- The next several lines configure the
contentItemsRequest. These statements tell the request which element and property fields to retrieve and how to sort the returned data. The app really only uses the title and cover properties, but this is an example of how you can request all sorts of information.
- The geo location data of the device can even be sent with the request, enabling the server to customize returned content based on the location of the user.
- The request is then executed by the
A couple questions have probably come to your mind at this point.
- “Where did that contentPath come from?”
- The first part of the content path
Samples/ is the MACM library name. Remember how you opened the “Samples” library in the console earlier?
- The next section of the path
Content Types/ says that you are retrieving content by type.
- The final section of the path says you are retrieving items of the content type
- There are several ways to query content. See https://ibm.biz/MACMQueryParams
- “What elements and properties are available for the
- This is determined by how the Book content type has been configured in the MACM server. Go back to your MACM dashboard where you have “Adventures of Huckelberry Finn” open and click the View JSON code button on the left menu. This shows you exactly what data could be sent by the server when a request is made for this content item. The advantage of specifying the elements and properties you want is that you can limit the data traffic to only what is needed by the mobile app.
Now, back to that
- After some error checking, the response data is iterated upon. For each item, a new Book instance is created. Since this app stores the data locally using CoreData, books are instances of
- The elements and properties of the return data are flattened into a values dictionary and used to fill in the details of the book.
dataController.saveManagedObjectContent is called. All this really does is ask the
ManagedObjectController to save the books that were created.
A URL to the book cover image is contained in the cover property of the book content item. When the user taps on a book in the list, the cover image must be fetched from that URL. In the original app, this is done with a regular
NSURLConnection request. Now your images will be coming from the MACM server.
- Open CAASExample/PageController/CoverController.swift.
- Navigate to the first TODO and uncomment the
import CAASObjC statement.
- Navigate to the next TODO.
- The images in our sample all come from the wikimedia.org server. Delete the declaration of
- Insert the snippet TUTORIALimageHostBaseURL. This will use a property on the
caasService as the base URL for image requests.
- Navigate to the final TODO in the file. The current
downloadImage function uses
NSURLConnection to request the image. You want to request the image through the
caasService so authentication and security requirements are met.
- Delete the downloadImage function.
- Insert the snippet TUTORIALdownloadImage to insert the following code:
- Cancel any pending requests
- create a
CAASAssetRequest for the given URL. This is similar to a
CAASItemsRequest but is specifically for assets such as images.
- Ask the
caasService to execute the request.
completionBlock stops the busy indicator, sets the cover image and unhides it, then adds the new image to the image cache.
Run the Book app
- With all the changes complete, Build and Run the app
- You should see your app populate with the book content defined on the MACM server now instead of the static books you saw earlier.
Add / change content
Now, let’s say the business owner needs to add that Moby Dick book in again. This time, instead of having you take time away from other tasks to add another book in code to make it happen, your Content Author (Marketing, LoB, etc.) will add the book through the MACM console and the change will be automatically picked up by the mobile app through the use of the MACM SDK.
- Return to your MACM Bluemix dashboard.
- Open the Samples library by clicking the Samples tile.
- Select Create Project from the Project drop-down list at the top of the page. Name the project Moby Dick.
- Select Book from the Create Content drop-down on the right.
- Fill in the attributes of the book:
- Click Submit for Review. Your new book will appear in the list with a “Draft” decorator. Since it is still Draft, it will not yet appear in the app. (It is possible to also query for Draft content with the SDK. See https://ibm.biz/MACMDraftContent.)
- Open the Projects menu.
- Select the Moby Dick content item and choose Approve from the Actions menu.
- Provide a comment and click Approve
- Click Publish Project
Re-run the app
If all goes well, “Moby Dick” will now appear in your list of books when you run your app.
This tutorial demonstrates how you can use IBM Mobile Application Content Manager to provide your users with adaptive content, improving their experience with your app. By leveraging adaptive content, you:
- Put the responsibility of adaptive content where it belongs – in the hands of the content owners
- Reduce the tedious, time-consuming and error-prone maintenance of content embedded in code
- Minimize your time to deliver new content
- Give your users a more personalized mobile experience
Start using IBM Mobile Application Content Manager on your own apps during our open beta period, going on now.