Composr Tutorial: Mobile apps via Composr Mobile SDK

Written by Chris Graham
Composr Mobile SDK ("CMS SDK") is a toolkit to help you build mobile apps that work with a central Composr-powered website. It is intended for use by experienced iOS and Android developers.

As well as containing Composr integrations, there are also a large collection of standalone utilities for building apps. These create a common base between iOS and Android that is reminiscent of the PHP and Composr APIs, allowing easier code porting while also remaining 100% native.

Table of contents

  1. Composr Tutorial: Mobile apps via Composr Mobile SDK
    1. Getting Composr Mobile SDK
      1. SDK
      2. Server-side functionality
    2. Setup
      1. iOS
      2. Android
    3. Using Composr Mobile SDK
      1. CMS_Arrays
        1. collapse_1d_complexity
        2. collapse_2d_complexity
        3. explode
        4. implode
        5. list_to_map
        6. array_values
        7. array_merge
        8. sort
        9. array_key_exists
        10. array_unique
        11. sort_maps_by
        12. count
        13. list_to_map
      2. CMS_Strings
        1. strip_tags
        2. html_entity_decode
        3. float_format
        4. strpos
        5. str_replace
        6. substr
        7. trim
        8. stringWithFormat
        9. strlen
      3. CMS_Langs
        1. do_lang
        2. do_lang: parameters:
      4. CMS_Preferences
        1. get_value
        2. set_value
      5. CMS_Timestamps
        1. get_timezoned_date_time
        2. get_timezoned_date
        3. time
      6. CMS_HTTP
        1. rawurlencode
        2. json_decode
        3. json_encode
        4. get_base_url
        5. build_url
        6. http_get_contents
        7. has_network_connection
      7. CMS_Users
        1. has_page_access
        2. has_privilege
        3. has_zone_access
        4. is_staff
        5. is_super_admin
        6. get_member
        7. get_session_id
        8. get_username
        9. get_members_groups
        10. get_members_groups_names
        11. get_password
      8. CMS_Flow
        1. access_denied
        2. attach_message
        3. inform_screen
        4. warn_screen
        5. redirect_screen
      9. CMS_Forms
        1. form_input_field_spacer_withHeading
        2. form_input_hidden_withParamName
        3. form_input_integer_withPrettyName
        4. form_input_float_withPrettyName
        5. form_input_line_withPrettyName
        6. form_input_password_withPrettyName
        7. form_input_list_withPrettyName
        8. form_input_text_withPrettyName
        9. form_input_tick_withPrettyName
        10. form_input_uploaded_picture_withPrettyName
        11. form_input_date_withPrettyName
        12. get_input_date
        13. post_param_string
        14. post_param_integer
        15. set_url
        16. set_button_withName
        17. do_http_post_request
        18. getFormValues
      10. CMS_Database
        1. createCopyOfDatabaseIfNeeded
        2. initializeDatabase
        3. create_table
        4. drop_table_if_exists
        5. add_table_field
        6. rename_table_field
        7. delete_table_field
        8. db_escape_string
        9. query
        10. query_delete
        11. query_insert
        12. query_select
        13. query_select_value
        14. query_select_int_value
        15. query_update
        16. getFieldNamesForTable
        17. upgradeDatabaseIfRequired
      11. CMS_Notification
        1. registerForRemoteNotifications
        2. parseDeviceToken
        3. notifyDeviceTokenToServer
        4. showNotification
      12. CMSNetworkManager
        1. GET
        2. POST
      13. More Utilities
        1. NumberInput
        2. ComboBox
        3. DatePicker
        4. PhotoUpload
    4. Notifications
    5. Toolkit
      1. Language files
      2. Image assets
    6. Server-side API
      1. Default available endpoints
    7. Other approaches to mobile integration
      1. Tapatalk
    8. See also

Getting Composr Mobile SDK

SDK

The main iOS/Android SDK can be found on GitLab.

Server-side functionality

To connect to a Composr site you will need to install the non-bundled composr_mobile_sdk addon.
This addon also contains some scripting to help generate app assets from the Composr site.

Setup

iOS

How to link the SDK into your project:
  1. Create a new project to use with CMS_SDK or open an existing project.
  2. Add a Prefix Header file (.pch) to your project if you do not have one (the prefix headers are not added automatically in Xcode6 created projects). Steps to add a pch file:
    • File → New →
    • iOS → Other → PCH File → ProjectName-Prefix.pch
    • Project > Build Settings > Search: "Prefix Header"
    • Under "Apple LLVM 6.0" you will get the Prefix Header key
    • Type in: ProjectName/ProjectName-Prefix.pch
    • Clean project
  3. Frameworks you need to add in Build Phases:
    • MobileCoreServices.framework
    • libz.dylib
    • CFNetwork.framework
    • libsqlite3.0.dylib
    • SystemConfiguration.framework
    • Foundation.framework
    • CoreGraphics.framework
    • UIKit.framework
  4. Now, add CMS_SDK entirely to your project by File → Add Files to <your_project_name>. Then, you can remove references of the files not required. Make sure you do not check the "Copy items if needed" option and add the required targets. Do not check "Copy items if needed".
  5. Once you have imported the entire SDK, you can remove references to unwanted files. You can also import the SDK without these files, but this would be easier. While deleting do not choose move to trash. because we have only references to CMS_SDK. So, give "Remove References". Files to be removed:
    • The xcode project file (Composr Mobile SDK.xcodeproj)
    • AppDelegate.h and AppDelegate.m
    • Entire Composr Mobile SDKTests folder
    • Supporting Files folder
  6. Click on your project icon and open the build settings tab. Scroll down to search paths, open header search paths by double clicking it. Add a path to the CMS_SDK folder here to let the compiler know the path to see the source files. Make sure you supply the option "Recursive" for this new entry.
  7. Now, you need to add a compiler option for the JsonKit library. Open the "Compile Sources" in "Build Phases" of your project. Scroll down to JSONKit.m and double click on it. In the pop-up that appears, give this text: -fno-objc-arc -Wno-conversion.
  8. Now, open up your pch file and import CMS_SDK.h so that the SDK is available in your entire project.
That's it. You are now good to go work with the features of CMS_SDK.

Android

How to link the SDK into your project, assuming you are using Eclipse:
  1. Create a new project to use with CMS_SDK, or open an existing project
  2. Import CMS_SDK into your workspace as an android project
  3. Open the "Properties" of CMS_SDK and make sure "is Library" is checked under the "Android" tab
  4. Now open the "Properties" of your project and add CMS_SDK as a dependent library
    • Open "Properties"
    • Choose the "Android" tab
    • Click "Add" button under the "Library" section
    • A dialog box opens up asking to select the library. Select CMS_SDK from the list and click "OK"
    • Click "OK" on the "Properties" dialog box
    • Eclipse should automatically rebuild your project (or) you can do a project cleanup from under Project → Clean.
  5. Now you can access all the features of CMS_SDK in your project.

If you are using Android Studio then the process would be similar. CMS SDK is implemented as a very conventional library.

Using Composr Mobile SDK

The SDK is very consistent between Android and iOS. Our documentation will be written in terms of iOS, but you should not have a problem writing for Android also.

We haven't provided code examples for everything, but the API has extensive automated test coverage. These tests show you expected behaviours clearly.

CMS SDK is fully Open Source, so all code can be inspected and contributions are welcome.

We use PHP terminology for data structures: lists and maps. In Android a list is the List interface (ArrayList, LinkedList, etc) and a map is the Map interface (HashMap, TreeMap, etc). In iOS a list is a NSArray and a map is a NSDictionary. In PHP they are actually both implemented as arrays, but the array internally is always held either a list or a map.

We use the PHP term "function". In iOS and Android a function is a method.

We use the iOS term "view controller". In Android this is an "activity".

Callbacks in particular have different implementations. We use the iOS term/concept "block". In Android this is generally implemented by passing an object matching a particular interface, and then a method is called upon it.

CMS_Arrays

The CMS_Arrays class provides the array operation functionalities. The class contains the following functions:

collapse_1d_complexity

Prototype:

Code (objc)

(NSArray *)collapse_1d_complexity:(NSString *)key :(NSArray *)arr;
 

Description:
Takes a list of maps and turns it into a simple list by extracting just one element from each map.

Usage:

Code (objc)

[CMS_Arrays collapse_1d_complexity :<key to be extracted> :<array>];
 

Example:
Let us consider that you have an array of maps. Each maps contains an ID and a title as keys. Using the collapse_1d_complexity function, you can get all the title key values from the array. The code will be:

Code (objc)

NSArray *inputArray = @[
        @{@"id" : @"1",@"title" : @"Belgium"},
        @{@"id" : @"2",@"title" : @"France"}
];
NSString *inputKey = @"title";
NSArray *output = [CMS_Arrays collapse_1d_complexity:inputKey :inputArray];
 
The output from above code will be: @[@"Belgium",@"France"]

collapse_2d_complexity

Prototype:

Code (objc)

(NSDictionary *)collapse_2d_complexity:(NSString *)keyKey :(NSString *)valKey :(NSArray *)arr;
 

Description:
Takes a list of maps and simplify by extracting two elements from each map. First element is kept as the key and second as value in the resultant map.

Usage:

Code (objc)

[CMS_Arrays collapse_2d_complexity:<key of key> :<key of val> :<array>];
 

Example:
Consider an array of maps with each map contains an ID and a title. You need to convert the array into a map by fetching two values from each map by keeping the first as the key and second as the value.

Code (objc)

NSArray *inputArray = @[
        @{@"id" : @"1",@"title" : @"Belgium"},
        @{@"id" : @"2",@"title" : @"France"}
];
NSString *inputKeyKey = @"id";
NSString *inputKeyVal = @"title";
 
By calling:
[CMS_Arrays collapse_2d_complexity:inputKeyKey :inputKeyVal:inputArray];
… you would get a dictionary of the following form:

Code (objc)

@{
        @"1" : @"Belgium",
        @"2" : @"France"
};
 
The values from the ID field is taken as key and the value of the title field is taken as value.

explode

Prototype:

Code (objc)

(NSArray *)explode:(NSString *)sep :(NSString *)str;
 

Description:
Similar to PHP explode functionality, will split multiple strings from input string. The function will return an array of strings, where each split is a substring of string formed by splitting it on boundaries formed by the string separator.

Usage:

Code (objc)

[CMS_Arrays explode:<separator string> :<source string>];
 

Example:
The example shown below is an instance with split strings separated by hyphens.

Code (objc)

NSString *source = @"This-is-an-example-string";
NSString *separator = @"-";
 
Calling [CMS_Arrays explode:separator :source]; will return an array of strings:

Code (objc)

@[@"This",@"is",@"an",@"example",@"string"];
 

implode

Prototype:

Code (objc)

(NSString *)implode:(NSString *)sep :(NSArray *)arr;
 

Description:
Implode will join multiple array elements to form a single string. The functionality is the same as in PHP implode.

Usage:

Code (objc)

[CMS_Arrays implode:<joiner string> :<source array>];
 

Example:
Code example on having an array of strings, and joining strings by using a hyphen, through implode.

Code (objc)

NSArray *source = @[@"This",@"is",@"an",@"example",@"string"];
NSArray *joiner = @"-";
 
Calling [CMS_Arrays implode:joiner :source]; will return a single string:

Code (objc)

@"This-is-an-example-string"
 

list_to_map

Prototype:

Code (objc)

(NSDictionary *)list_to_map:(NSString *)key :(NSArray *)dict;
 

Description:
Take a list of maps, and make one of the values of each array the index of a map to the map.
list_to_map is very useful for handling query results. Let's imagine you get the result of SELECT id,title FROM sometable. list_to_map turns the array of rows into a map between the ID key and each row.

Usage:

Code (objc)

[CMS_Arrays list_to_map:<key> :<source array>];
 

Example:
The below example code will restructure the given list of maps into a map of maps.

Code (objc)

NSArray *source = @[
        @{
                @"key1":@"valA1",
                @"key2":@"valA2"
        },
        @{
                @"key1":@"valB1",
                @"key2":@"valB2"
        }
];
 
Calling [CMS_Arrays list_to_map:keyA1 :source]; will return:

Code (objc)

@{
        @"valA1":@{
                @"key1":@"valA1",
                @"key2":@"valA2"
        }
},
@{
        @"valB1":@{
                @"key1":@"valB1",
                @"key2":@"valB2"
        }
}
 

array_values

Prototype:

Code (objc)

(NSArray *)array_values:(BOOL)useKey :(NSDictionary *)dict;
 

Description:
array_values will return either all keys or all values from a map based on the boolean value that is set.

Usage:

Code (objc)

[CMS_Arrays array_values:<want keys ?> :<source map>];
 

Example:
The below example code will return only keys from the map if the value is set to YES, otherwise will return only values from a map that contains many keys and values.

Code (objc)

NSDictionary *source = @{
        @"key1":@"val1",
        @"key2":@"val2"
};
 
Calling [CMS_Arrays array_values:YES :source]; will return:

Code (objc)

@[@"key1",@"key2"]
 
Calling [CMS_Arrays array_values:NO :source]; will return:

Code (objc)

@[@"val1",@"val2"]
 

array_merge

Prototype:

Code (objc)

(NSArray *)array_merge:(NSArray *)array1 :(NSArray *)array2;
 

Description:
array_merge will return an array containing all values from array1 and array2.

Usage:

Code (objc)

[CMS_Arrays array_merge:<array 1> :<array 2>];
 

Example:
The below example code will return merged array from the given two input arrays.

Code (objc)

NSArray *inputArray1 = @[@1, @2, @"3", @"test", @5.3];
NSArray *inputArray2 = @[@6, @2, @"fdfd"];
 
Calling [CMS_Arrays array_merge:inputArray1 :inputArray2]; will return:

Code (objc)

@[@1, @2, @"3", @"test", @5.3, @6, @2, @"fdfd"]
 

sort

Prototype:

Code (objc)

(void)sort:(NSArray *)array;
 

Description:
sort will sort an array of strings or numbers. It works by reference: the passed array reference will get modified directly.

Usage:

Code (objc)

[CMS_Arrays sort:<array reference>];
 

Example:
The below example code will sort the given array.

Code (objc)

NSArray *array = @[@4, @"-1", @"1", @0];
 
Calling [CMS_Arrays sort:&array]; will sort the passed array as:

Code (objc)

@[@"-1", @0, @"1", @4]
 

array_key_exists

Prototype:

Code (objc)

(BOOL)array_key_exists:(NSString *)key :(NSDictionary *)map;
 

Description:
array_key_exists will check if a map contains the provided key.

Usage:

Code (objc)

[CMS_Arrays array_key_exists:<key> :<map>];
 

Example:
The below example code will check if the given array contains the specified key.

Code (objc)

NSDictionary *inputMap =  @{
                                @"key1":@"val1",
                                @"key2":@"val2",
                                @"3.6":@"val6"
                                };
 
Calling [CMS_Arrays array_key_exists:@"key1" :inputMap]; will return true.
Calling [CMS_Arrays array_key_exists:@"3.6" :inputMap]; will return true.

array_unique

Prototype:

Code (objc)

(NSArray *)array_unique:(NSArray *)array;
 

Description:
array_unique will remove all duplicate entries from the array.

Usage:

Code (objc)

[CMS_Arrays array_unique:<array>];
 

Example:
The below example code will return an array by removing duplicates from the given array.

Code (objc)

NSArray *inputArray = @[@1, @2, @2, @"3", @"test", @5.3, @"test", @3];
 
Calling [CMS_Arrays array_unique:inputArray]; will return:

Code (objc)

@[@1, @2, @"3", @"test", @5.3]
 

sort_maps_by

Prototype:

Code (objc)

(void)sort_maps_by:(NSString *)key :(NSArray *)array;
 

Description:
sort_maps_by will sort an array of maps with the value for the key provided. It works by reference: the passed array reference will get modified.

Usage:

Code (objc)

[CMS_Arrays sort_maps_by:<key> :<array of maps>];
 

Example:
The below example code will sort the given array of maps according to the values of the key "id".

Code (objc)

NSArray *inputArray = @[
                            @{
                                @"id":@1,
                                @"val":@"val5"
                                },
                            @{
                                @"id":@3,
                                @"val":@"val2"
                                },
                            @{
                                @"id":@0,
                                @"val":@"Val9"
                                }
                            ];
 
Calling [CMS_Arrays sort_maps_by:&inputArray :@"id"]; will sort the array of maps as:

Code (objc)

@[
    @{
        @"id":@0,
        @"val":@"Val9"
        },
    @{
        @"id":@1,
        @"val":@"val5"
        },
    @{
        @"id":@3,
        @"val":@"val2"
        }
]
 

count

Prototype:

Code (objc)

(int)count:(id)array;
 

Description:
count will return the number of objects in an array/map.

Usage:

Code (objc)

[CMS_Arrays count:<array/map>];
 

Example:
The below example code will return the count of values in an array or number of keys in a map.

Code (objc)

NSArray *array = @[@4, @"-1", @"1", @0];
 
Calling [CMS_Arrays count:array]; will return 4.

Code (objc)

NSDictionary *map = @{
                          @"key1":@"val1",
                          @"key2":@"val2",
                          @"key3":@"val3",
                          @"key4":@"val4",
                          @"key5":@"val5"
                          };
 
Calling [CMS_Arrays count:map]; will return 5.

list_to_map

Prototype:

Code (objc)

(NSDictionary *) list_to_map:(NSString *)key :(NSArray *)list;
 

Description:
list_to_map will return map corresponding to a key from array of maps.

Usage:

Code (objc)

[CMS_Arrays list_to_map:<key> :<list of maps>];
 

Example:
The below example code will return map with keys as value of the given key from each map in the array.

Code (objc)

NSArray *inputList = @[
                        @{
                            @"id" : @"1",
                            @"val" : @"val1"
                        },
                        @{
                            @"id" : @"2",
                            @"val" : @"val2"
                        },
                        @{
                            @"id" : @"3",
                            @"val" : @"val3"
                        }
                    ];
 
Calling [CMS_Arrays list_to_map:@"id" :inputList]; will return:

Code (objc)

@{
          @"1" : @{
                   @"id" : @"1",
                   @"val" : @"val1"
                  },
          @"2" : @{
                   @"id" : @"2",
                   @"val" : @"val2"
                  },
          @"3" : @{
                   @"id" : @"3",
                   @"val" : @"val3"
                  }
};
 

CMS_Strings

CMS_Strings functions provide common string operation functionalities.

strip_tags

Prototype:

Code (objc)

(NSString *)strip_tags:(NSString *)str;
 

Description:
Removes all the HTML tags from the input string.

Usage:

Code (objc)

[CMS_Strings strip_tags:<input string>];
 

Example:
Consider the scenario where a string returned from a web service contains few HTML tags. These unwanted HTML tags can be removed by using strip_tags.

Code (objc)

NSString *inputString = @"Hi. </br>How are you?";
 
Calling [CMS_Strings strip_tags:inputString]; will return:

Code (objc)

@"Hi. How are you?"
 

html_entity_decode

Prototype:

Code (objc)

(NSString *)html_entity_decode:(NSString *)str;
 

Description:
Convert the common HTML entity into standard keyboard characters. For example, the entity &amp; will be converted to &.

Usage:

Code (objc)

[CMS_Strings html_entity_decode:<input string>]
 

Example:
Consider that an HTML entity is present for double quotes in your string returned from a query. These entities can be converted to keyboard characters by calling the html_entity_decode function:

Code (objc)

NSString *inputString = @"&ldquo;I love cats &amp; dogs&ldquo;";
 
Calling [CMS_Strings html_entity_decode:inputString]; will return:

Code (objc)

@"\"I love cats & dogs\"".
 

float_format

Prototype:

Code (objc)

(NSString *)float_format:(double)number :(int)decimalPoints :(BOOL)onlyIncludeNeededDecimalPoints;
 

Description:
Formats a number value nicely by including commas and decimal points wherever applicable.

Usage:

Code (objc)

[CMS_Strings float_format:<input double value> :<number of required decimal points> :<should consider the second param ?>];
 

Example:

Code (objc)

double input = 12345678.012110;
 
[CMS_Strings float_format:input :0 :NO] will return @"12,345,678.01211"
[CMS_Strings float_format:input :0 :YES] will return @"12,345,678"
[CMS_Strings float_format:input :2 :YES] will return @"12,345,678.01"

strpos

Prototype:

Code (objc)

(int)strpos:(NSString *)searchIn :(NSString *)searchFor;
 

Description:
strpos works similarly to the functionality available in PHP's strpos. The function is used to find the position of the first occurrence of a substring in a string. If not found, then will return -1.

Usage:

Code (objc)

[CMS_Strings strpos:<input string> :<search string>]
 

Example:
For example, if you need to find the starting position of "s" in the string "I love cats and dogs" then strpos can be used.
Calling [CMS_Strings strpos:"I love cats and dogs" :@"s"] will return 10.

str_replace

Prototype:

Code (objc)

(NSString *)str_replace:(NSString *)search :(NSString *)replace :(NSString *)searchIn;
 

Description:
Similar to the common search and replace string functionality in PHP. The str_replace function will replace all the instances of the search string with the provided replacement string.

Usage:

Code (objc)

[CMS_Strings str_replace:<search_string> :<replace_string> :<input_string>]
 

substr

Prototype:

Code (objc)

(NSString *)substr:(NSString *)searchIn :(int)offset :(int)length;
 

Description:
The function returns the portion of string specified by the offset and length parameters.

Usage:

Code (objc)

[CMS_Strings substr:<input_string> :<start_position> :<length to be copied>]
 

trim

Prototype:

Code (objc)

(NSString *)trim:(NSString *)str;
 

Description:
To strip the whitespace and newline characters from the beginning and end of a string, the trim function can be used.

Usage:

Code (objc)

[CMS_Strings trim:<input_string>]
 

stringWithFormat

Prototype:

Code (objc)

(NSString *)stringWithFormat:(NSString *)format array:(NSArray *)arguments;
 

Description:
The stringWithFormat function is to replace the %@ strings from the string array values in the source string.

Usage:

Code (objc)

[CMS_Strings stringWithFormat:<input_strings> array:<replace arguments>];
 

Example:
Consider that there is a generic string template from a web API saying @"Hi %@. Welcome to %@". Use the stringWithFormat function to substitute first instance of %@ the user's name and the second instance with forum name.
Calling [CMS_Strings stringWithFormat:@"Hi %@. Welcome to %@" array:@[@"Allen",@"CMS"]]; will return:

Code (objc)

@"Hi Allen. Welcome to CMS"
 

strlen

Prototype:

Code (objc)

(int)strlen:(NSString *)str;
 

Description:
To get the length of a string, the strlen function can be used.

Usage:

Code (objc)

[CMS_Strings strlen:<input_string>]
 

CMS_Langs

The CMS_Langs class provides all the necessary localisation functions. The common localisation functions are available via the two variants of the do_lang function (with or without parameters).

do_lang

Prototype:

Code (objc)

(NSString *)do_lang:(NSString *)key
 

Description:
The do_lang function returns the localised value of the supplied input key string from the localizable.strings file, based on the device language.

Usage:

Code (objc)

[CMS_Langs do_lang:inputString]
 

do_lang: parameters:

Prototype:

Code (objc)

(NSString *)do_lang:(NSString *)strName :(NSArray *)parameters;
 

Description:
Returns the localised value of the string after replacing the string with arguments.

Usage:

Code (objc)

[CMS_Langs do_lang:<input_string> :<arguments>]
 

Example:
[CMS_Langs do_lang:@"%@_%@" :@[@"EXAMPLE",@"STRING"]]; will find the localised version of string found by replacing @"%@_%@" with the arguments given. So, it will return the localised version of @"EXAMPLE_STRING".

CMS_Preferences

The CMS_Preferences class provides the common functions used to define the user default preferences.

get_value

Prototype:

Code (objc)

(NSString *)get_value:(NSString *)string;
 

Description:
Get the default value from NSUserDefaults.

Usage:

Code (objc)

[CMS_Preferences get_value:<key>]
 

set_value

Prototype:

Code (objc)

(void)set_value:(NSString *)name :(NSString *)value;
 

Description:
Assign a default value for key, to NSUserDefaults.

Usage:

Code (objc)

[CMS_Preferences set_value:<key> :<value>]
 

CMS_Timestamps

Timestamp-related functionalities such as get_timezoned_date_time and time are available as functions under the CMS_Timestamps class.

get_timezoned_date_time

Prototype:

Code (objc)

(NSString *)get_timezoned_date_time:(int)timestamp;
 

Description:
Converts the given timestamp to @"MMM dd, yyyy - HH:mm:ss" date format and returns the value as a string.

Usage:

Code (objc)

[CMS_Timestamps get_timezoned_date:<timestamp> :<includeTime ?>]
 

get_timezoned_date

Prototype:

Code (objc)

(NSString *)get_timezoned_date:(int)timestamp;
 

Description:
Converts the given timestamp to @"MMM dd, yyyy" date format and returns the value as a string.

Usage:

Code (objc)

[CMS_Timestamps get_timezoned_date:<timestamp> :<includeTime ?>]
 

time

Prototype:

Code (objc)

(int)time;
 

Description:
Returns the UNIX timestamp.

Usage:

Code (objc)

[CMS_Timestamps time]
 

CMS_HTTP

The CMS_HTTP class provides functions needed while connecting and parsing web services. This class contains the following functions:

rawurlencode

Prototype:

Code (objc)

(NSString *)rawurlencode:(NSString *)str;
 

Description:
Returns a string in which all non-alphanumeric characters except -_.~ will be replaced with a percentage (%) symbol, followed by two hexadecimal digits. This is the encoding described in RFC 3986 for protecting the literal characters from being interpreted as special URL delimiters. For example, within URL parameters.

Usage:

Code (objc)

[CMS_HTTP rawurlencode:<input_string>]
 

Example:

Code (objc)

NSString *inputString = @"test encoding the url + something";
 
Calling [CMS_HTTP rawurlencode:inputString] will return:

Code (objc)

@"test%20encoding%20the%20url%20%2B%20something"
 

json_decode

Prototype:

Code (objc)

(id) json_decode:(NSString *)value;
 

Description:
Takes a JSON encoded string and converts it into a corresponding Objective-C variable.

Usage:

Code (objc)

[CMS_HTTP json_decode:<input_json_string>]
 

Example:

Code (objc)

NSString *jsonString = @"{\"test\":\"val\",\"test1\":\"val1\"}";
 
Calling [CMS_HTTP json_decode:jsonString] will return a dictionary of the form:

Code (objc)

@{
        @"test" : @"val",
        @"test1" : @"val1"
};
 

json_encode

Prototype:

Code (objc)

(NSString *)json_encode:(id)value;
 

Description:
Returns a string containing the JSON representation of an Objective-C variable.

Usage:

Code (objc)

[CMS_HTTP json_encode:<input_objc_variable>]
 

Example:

Code (objc)

NSDictionary *inputDict = @{
        @"test" : @"val",
        @"test1" : @"val1"
};
 
Calling [CMS_HTTP json_encode:inputDict] will return the string of the form:

Code (objc)

@"{\"test\":\"val\",\"test1\":\"val1\"}"
 

get_base_url

Prototype:

Code (objc)

(NSString *)get_base_url;
 

Description:
Gets the base URL to the Composr website, defined for the project in CMS_Constants.h.

Usage:

Code (objc)

[CMS_HTTP get_base_url]
 

build_url

Prototype:

Code (objc)

(NSString *)build_url:(NSDictionary *)params :(NSString *)zone;
 

Description:
Returns a URL with the given parameters and zone name using the format:
<base_url>/<zone>/index.php?<params...>

Usage:

Code (objc)

[CMS_HTTP build_url:<params> :<zone_name>]
 

Example:
Calling [CMS_HTTP build_url:@{@"param1":@"value1",@"param2":@"value2"} :@"testZone"] will return:

Code (objc)

@"http://<base_url>/testZone/index.php?&param1=value1&param2=value2"
 

http_get_contents

Prototype:

Code (objc)

(void)http_get_contents:(NSString *)url :(BOOL)triggerError :(NSDictionary *)postParams :(int)timeoutInSeconds :(CMSCompletedDownloadBlock)completionHandler;
 

Description:
Downloads the response from the web service and returns as a response in a completion handler. If the triggerError is TRUE, then a failure will be displayed as a generic error alert. If postParams is not nil then it will be an HTTP post.

Usage:

Code (objc)

[CMS_HTTP http_get_contents:<web service url> :<trigger_error ?> :<post parameters> :<custom_timeout_value> :<completion_handler>];
 

Example:
Calling:

Code (objc)

[CMS_HTTP http_get_contents:<url> :YES :nil :kHTTPTimeout :^(NSString *response) {
        NSLog(@"%@",response);
}];
 
… will print the response of the resulting web service call.

has_network_connection

Prototype:

Code (objc)

(BOOL) has_network_connection;
 

Description:
Check and return a boolean value based on the Internet connectivity available for the app. The function will check whether the app is connected to the Internet or not.

Usage:

Code (objc)

[CMS_HTTP has_network_connection]
 

CMS_Users

The CMS_Users class provides user-related functionalities such as retrieve member, usergroup, and privilege information from Composr to the app (this data is synced during login).

When a successful login is executed using CMSNetworkManager, each value from the resultant JSON response is stored in the NSUserDefaults. Also, the values inside the user_data key are extracted and saved into NSUserDefaults. The CMS_Users class provides a Composr-like way of accessing this information.

This class contains the following functions:

has_page_access

Prototype:

Code (objc)

(BOOL)has_page_access:(NSString *)pageName;
 

Description:
Returns a boolean value indicating if the user has access to a particular page in Composr.

Usage:

Code (objc)

[CMS_Users has_page_access:@"example"]
 

has_privilege

Prototype:

Code (objc)

(BOOL)has_privilege:(NSString *)privilegeName;
 

Description:
Returns a boolean value if the user has a particular privilege on their account in Composr.

Usage:

Code (objc)

[CMS_Users has_privilege:<privilege_name>]
 

has_zone_access

Prototype:

Code (objc)

(BOOL)has_zone_access:(NSString *)zoneName;
 

Description:
Returns a boolean value after checking whether the user has the access to a particular zone in Composr.

Usage:

Code (objc)

[CMS_Users has_zone_access:<zone_name>]
 

is_staff

Prototype:

Code (objc)

(BOOL)is_staff;
 

Description:
Returns a boolean value if the user is staff or not in Composr.

Usage:

Code (objc)

[CMS_Users is_staff]
 

is_super_admin

Prototype:

Code (objc)

(BOOL)is_super_admin;
 

Description:
Returns a boolean value if the user is an administrator or not in Composr.

Usage:

Code (objc)

[CMS_Users is_super_admin]
 

get_member

Prototype:

Code (objc)

(int)get_member;
 

Description:
Returns the member ID of the user in Composr.

Usage:

Code (objc)

[CMS_Users get_member]
 

get_session_id

Prototype:

Code (objc)

(int)get_session_id;
 

Description:
Returns the session ID of the user in Composr.

Usage:

Code (objc)

[CMS_Users get_session_id]
 

get_username

Prototype:

Code (objc)

(NSString *)get_username;
 

Description:
Returns the username of logged in user.

Usage:

Code (objc)

[CMS_Users get_username]
 

get_members_groups

Prototype:

Code (objc)

(NSArray *)get_members_groups;
 

Description:
Returns all the details of member groups a user has in Composr. This is a list of maps, with each map containing 'id' and 'name'.

Usage:

Code (objc)

[CMS_Users get_members_groups]
 

get_members_groups_names

Prototype:

Code (objc)

(NSArray *)get_members_groups_names;
 

Description:
Returns only names of the member groups a user had in Composr.

Usage:

Code (objc)

[CMS_Users get_members_groups_names]
 

get_password

Prototype:

Code (objc)

(NSString *)get_password;
 

Description:
Returns the password of the user saved in NSUserDefaults.

Usage:

Code (objc)

[CMS_Users get_password]
 

CMS_Flow

The CMS_Flow class provides functions that you can use to control the flow of your app. This class contains the following functions:

access_denied

Prototype:

Code (objc)

(void)access_denied;
 

Description:
Dismisses any screen that is shown now and presents the login page as root controller.

Usage:

Code (objc)

[CMS_Flow access_denied];
 

attach_message

Prototype:

Code (objc)

(void)attach_message:(NSString *)msg;
 

Description:
Pops up an alert with the given message. The alert title will be "Message".

Usage:

Code (objc)

[CMS_Flow attach_message:<some_text>];
 

inform_screen

Prototype:

Code (objc)

(void)inform_screen:(NSString *)msg :(UIViewController *)viewController;
 

Description:
Pops up an alert with the given message. The alert title will be "Message". Automatically dismisses the calling view controller.

Usage:

Code (objc)

[CMS_Flow inform_screen:<some_text> :<presenting_controller_instance>];
 

warn_screen

Prototype:

Code (objc)

(void)warn_screen:(NSString *)msg :(UIViewController *)viewController;
 

Description:
Pops up an alert with the given message. The alert title will be "Warning". Automatically dismisses the calling view controller.

Usage:

Code (objc)

[CMS_Flow warn_screen:<some_text> :<presenting_controller_instance>];
 

redirect_screen

Prototype:

Code (objc)

(void)redirect_screen:(UIViewController *)sourceViewController :(UIViewController *)viewController;
 

Description:
Open a new view controller modally from the sourceViewController.

Usage:

Code (objc)

[CMS_Flow redirect_screen:<source_controller_instance> :<destination_controller_instance>];
 

CMS_Forms

The forms-related functionalities is provided in the CMS_Forms class. This works like as a form builder. The CMS_Forms class itself is a subclass of the UIView class and can be added as a subview into any view. All the functions in this class are instance methods. So, you will need an instance of the class to access the features.

For including the form in full screen on a controller, use:

Code (objc)

CMS_Forms *form = [[CMS_Forms alloc] initWithFrame:self.view.frame];
[self.view addSubview:form];
 

The class has a delegate variable which can be used to get responses of form submissions and such communications.

All the form field adding functions have the following common parameters:
  • prettyName: Text that is displayed as the form field placeholder.
  • description: String that is shown as an instruction text of the field above it.
  • paramName: This will be the parameter name of the value for the particular form field when sending an HTTP request.
  • defaultValue: The default value that will be populated in the form field
  • isRequired: A boolean value used to set whether a form field is mandatory or optional. When submitting a form, the unfilled form fields will be shown in red and the delegate will be notified through the preSubmitCallback.

The class contains the following functions:

form_input_field_spacer_withHeading

Prototype:

Code (objc)

(void)form_input_field_spacer_withHeading:(NSString *)heading withText:(NSString *)text;
 

Description:
Adds a heading into the form.

Usage:

Code (objc)

[form_instance form_input_field_spacer_withHeading:<heading text>withText:<sub_heading text>];
 

form_input_hidden_withParamName

Prototype:

Code (objc)

(void)form_input_hidden_withParamName:(NSString *)paramName withParamValue:(NSString *)paramValue;
 

Description:
Insert a hidden form parameter which is only considered when submitting the form. This hidden form will not appear anywhere in the UI.

Usage:

Code (objc)

[form_instance form_input_hidden_withParamName:<param_name> withParamValue:<param_value>];
 

form_input_integer_withPrettyName

Prototype:

Code (objc)

(id)form_input_integer_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withDefaultValue:(NSString *)defaultValue isRequired:(BOOL)isRequired;
 

Description:
Inserts an integer only input control. The input control will not accept decimal points, alphabetical characters, or special characters.

Usage:

Code (objc)

[form_instance form_input_integer_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withDefaultValue:<default_value>
                isRequired:<is_required ?>];
 

form_input_float_withPrettyName

Prototype:

Code (objc)

(id)form_input_float_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withDefaultValue:(NSString *)defaultValue isRequired:(BOOL)isRequired;
 

Description:
Inserts a floating point input control and will not accept alphabetical characters, or special characters.

Usage:

Code (objc)

[form_instance form_input_float_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withDefaultValue:<default_value>
                isRequired:<is_required ?>];
 

form_input_line_withPrettyName

Prototype:

Code (objc)

(id)form_input_line_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withDefaultValue:(NSString *)defaultValue isRequired:(BOOL)isRequired;
 

Description:
Inserts a string input control similar to an HTML input box. There are no validations: it will accept any type of characters.

Usage:

Code (objc)

[form_instance form_input_line_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withDefaultValue:<default_value>
                isRequired:<is_required ?>];
 

form_input_password_withPrettyName

Prototype:

Code (objc)

(id)form_input_password_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withDefaultValue:(NSString *)defaultValue isRequired:(BOOL)isRequired;
 

Description:
Inserts a password input control similar to an HTML password input box. There are no validations: it will accept any type of characters but display as password dots.

Usage:

Code (objc)

[form_instance form_input_password_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withDefaultValue:<default_value>
                isRequired:<is_required ?>];
 

form_input_list_withPrettyName

Prototype:

Code (objc)

(id)form_input_list_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withOptions:(NSDictionary *)options withDefaultValue:(NSString*)defaultValue isRequired:(BOOL)isRequired;
 

Description:
Inserts a combo-box type control. Options is a map between actual values and the displayed labels. The functionality is the same as the <option> in an HTML <select> control. The default value is the actual value (not an index) to be selected by default.

Usage:

Code (objc)

[form_instance form_input_list_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withOptions:<options_map>
                withDefaultValue:<default_value>
                isRequired:<is_required ?>];
 

Example:

Code (objc)

[form_instance form_input_list_withPrettyName:@"gender"
                withDescription:@"Gender"
                withParamName:@"gender"
                withOptions:@{
                        @"male":@"Male",
                        @"female":@"Female",
                        @"other":@"Other"
                }
                withDefaultValue:@"male"
                isRequired:YES];
 

form_input_text_withPrettyName

Prototype:

Code (objc)

(id)form_input_text_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withDefaultValue:(NSString *)defaultValue isRequired:(BOOL)isRequired;
 

Description:
Inserts a multiline text input control.

Usage:

Code (objc)

[form_instance form_input_text_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withDefaultValue:<default_value>
                isRequired:<is_required ?>];
 

form_input_tick_withPrettyName

Prototype:

Code (objc)

(id)form_input_tick_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName withDefaultValue:(BOOL)defaultValue;
 

Description:
Inserts a checkbox (aka switch) control. This is equivalent to a two-option-only radio input. The form value will be either 0 or 1.

Usage:

Code (objc)

[form_instance form_input_tick_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                withDefaultValue:<default_value>];
 

Example:

Code (objc)

[form_instance form_input_tick_withPrettyName:@"Subscribe to newsletter?"
                withDescription:@""
                withParamName:@"subscribe"
                withDefaultValue:NO];
 

form_input_uploaded_picture_withPrettyName

Prototype:

Code (objc)

(id)form_input_uploaded_picture_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName isRequired:(BOOL)isRequired;
 

Description:
Inserts a photo upload control. Picks a photo from user photo library or shows an option to capture photo using camera.

Usage:

Code (objc)

[form_instance form_input_uploaded_picture_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                isRequired:<is_required ?>];
 

Example:

Code (objc)

[form_instance form_input_uploaded_picture_withPrettyName:@"profilePic"
                withDescription:@"upload your profile pic"
                withParamName:@"profilePic"
                isRequired:YES];
 

form_input_date_withPrettyName

Prototype:

Code (objc)

(id)form_input_date_withPrettyName:(NSString *)prettyName withDescription:(NSString *)description withParamName:(NSString *)paramName isRequired:(BOOL)isRequired withDefaultValue:(NSString *)defaultValue includeTimeChoice:(BOOL)includeTimeChoice;
 

Description:
Inserts a date picker control. includeTimeChoice determines whether the date picker should show time or not.

Usage:

Code (objc)

[form_instance form_input_date_withPrettyName:<pretty_name>
                withDescription:<description>
                withParamName:<param_name>
                sRequired:<is_required ?>
                withDefaultValue:<default_value>
                includeTimeChoice:<show time ?>];
 

Example:

Code (objc)

[form_instance form_input_date_withPrettyName:@"DOB"
                withDescription:@"Provide your DOB :"
                withParamName:@"dob"
                isRequired:YES
                withDefaultValue:@""
                includeTimeChoice:NO];
 

get_input_date

Prototype:

Code (objc)

(int)get_input_date:(NSString *)paramName;
 

Description:
Get UNIX timestamp from a date input field (form_input_date_withPrettyName) in the form with the given paramName.

Usage:

Code (objc)

[form_instance get_input_date:<paramName>];
 

Example:
Calling:

Code (objc)

[form_instance get_input_date:@"DOB"];
 
… returns the timestamp of the DOB date input field. The previous example mentioned for form_input_date_withPrettyName is relevant.

post_param_string

Prototype:

Code (objc)

(NSString *)post_param_string:(NSString *)paramName;
 

Description:
Gets the string value from an input field in a form with the given paramName.

Usage:

Code (objc)

[form_instance post_param_string:<paramName>];
 

post_param_integer

Prototype:

Code (objc)

(int)post_param_integer:(NSString *)paramName;
 

Description:
Gets int value from an input field in a form with the given paramName.

Usage:

Code (objc)

[form_instance post_param_integer:<paramName>];
 

set_url

Prototype:

Code (objc)

(void)set_url:(NSString *)url;
 

Description:
Sets the URL to which the form is submitted. This is similar to the action attribute of an HTML form.

Usage:

Code (objc)

[form_instance set_url:<url>];
 

set_button_withName

Prototype:

Code (objc)

(void)set_button_withName:(NSString *)name preSubmitGuard:(SEL)preSubmitGuard postCallback:(SEL)postCallback autoSubmit:(BOOL)autoSubmit;
 

Description:
Sets the form's submit button. preSubmitGuard is the selector that will be called in case of validation failure while sending the form. postCallback is the selector that is called after the form submit is finished. All selectors will be executed in the delegate.
  • By default, the submit button will be executing the validation. If the validation fails, then the preSubmitGuard is called and if it succeeds, the postCallback will be called. This feature can be used if the form is not needed to be submitted on an HTTP URL. This feature is available in the CMS_SDK_Sample app.
  • If autoSubmit is TRUE, then the submit button will automatically trigger the HTTP form submit if the validation is successful.

Usage:

Code (objc)

[form_instance set_button_withName:@"Done"
                preSubmitGuard:<validation_error_callback_selector>
                postCallback:<submit_success_callback_selector>
                autoSubmit:<autoSubmit ?>];
 

Example:

Code (objc)

[form_instance set_button_withName:@"Done"
                preSubmitGuard:@selector(validationError)
                postCallback:@selector(callback)
                autoSubmit:YES];
 

do_http_post_request

Prototype:

Code (objc)

(void)do_http_post_request;
 

Description:
Execute the form HTTP submit. Will call the preSubmitGuard if validation fails and the submit process will be aborted. If the validation succeeds, then it will call postCallback after the HTTP submit is completed. The screen will be blocked automatically with a loader when the HTTP submit happens.

Usage:

Code (objc)

[form_instance do_http_post_request];
 

getFormValues

Prototype:

Code (objc)

(NSDictionary *)getFormValues;
 

Description:
Returns a map of all the values of the form with each paramName as the keys and entered values as values.

Usage:

Code (objc)

[form_instance getFormValues];
 

CMS_Database

This class provides the functions that you will need to access a SQLite database. The class functionality is similar to the Composr database class. So, you can access the database the same way you access your SQL database on the Composr. You can also set up the custom database upgrading code (not something possible out of the box with SQLite).

The functions are:

createCopyOfDatabaseIfNeeded

Prototype:

Code (objc)

(void)createCopyOfDatabaseIfNeeded;
 

Description:
Looks for an cms_DB.sqlite named file in the project bundle. If a similar file does not exist in the documents directory (i.e. within the live app filesystem) then this file is copied into it. If the project is run with the flag database_reset, the file in the documents directory is forcefully rewritten. These techniques can be used to include an initial version of the database packed within your project.

Usage:

Code (objc)

[CMS_Database createCopyOfDatabaseIfNeeded];
 

initializeDatabase

Prototype:

Code (objc)

(void)initializeDatabase;
 

Description:
This function opens the connection to the database. It must be called before executing any of the below functions to ensure that the connection to the database is established.

Usage:

Code (objc)

[CMS_Database initializeDatabase];
 

create_table

Prototype:

Code (objc)

(void)create_table:(NSString *)tableName :(NSArray *)fieldNames;
 

Description:
Create a table. Note that because we are using SQLite (a typeless database), we do not need to specify any field types.

Usage:

Code (objc)

[CMS_Database create_table:<table_name> :<field_names_array>];
 

Example:

Code (objc)

NSString *tableName = @"testTable";
NSArray *fields = @[
        @"field1",
        @"field2"
];
[CMS_Database create_table:tableName :fields];
 

drop_table_if_exists

Prototype:

Code (objc)

(void)drop_table_if_exists:(NSString *)tableName;
 

Description:
Delete a table.

Usage:

Code (objc)

[CMS_Database drop_table_if_exists:<table_name>];
 

add_table_field

Prototype:

Code (objc)

(void)add_table_field:(NSString *)tableName :(NSString *)fieldName;
 

Description:
Adds a new column to the table.

Usage:

Code (objc)

[CMS_Database add_table_field:<table_name> :<field_name>];
 

rename_table_field

Prototype:

Code (objc)

(void)rename_table_field:(NSString *)tableName :(NSString *)oldFieldName :(NSString *)newFieldName;
 

Description:
Renames a table column.

Usage:

Code (objc)

[CMS_Database rename_table_field:<table_name> :<old_field_name> :<new_field_name>];
 

delete_table_field

Prototype:

Code (objc)

(void)delete_table_field:(NSString *)tableName :(NSString *)fieldName;
 

Description:
Delete a column from the table.

Usage:

Code (objc)

[CMS_Database delete_table_field:<table_name> :<delete_field_name>];
 

db_escape_string

Prototype:

Code (objc)

(NSString *)db_escape_string:(NSString *)value;
 

Description:
Escapes any single quote strings so we can embed them within a quoted portion of SQL.

Usage:

Code (objc)

[CMS_Database db_escape_string:<string_to_be_escaped>]
 

query

Prototype:

Code (objc)

(NSArray *)query:(NSString *)query;
 

Description:
Executes the query and returns an array of resultant rows. Each row is represented as a map. Values in the row will be presented with column names as the map keys.

Usage:

Code (objc)

[CMS_Database query:<query>];
 

query_delete

Prototype:

Code (objc)

(void)query_delete:(NSString *)tableName :(NSDictionary *)whereMap;
 

Description:
Delete a specific set of rows based on any number of equality-test conditions provided in whereMap. i.e. each key value pair in whereMap will be converted into key=value checks in the SQL. No other condition types are supported (so no "OR" checks etc).

Usage:

Code (objc)

[CMS_Database query_delete:<table_name> :<where_map>];
 

Example:

Code (objc)

NSString *tableName = @"testTable";
NSDictionary *deleteWhereMap = @{
        @"field2":@"value22"
};
[CMS_Database query_delete:tableName :deleteWhereMap];
 
Executing
[CMS_Database query_delete:tableName :deleteWhereMap];
is equivalent to running - DELETE FROM testTable WHERE field2='value22';

query_insert

Prototype:

Code (objc)

(void)query_insert:(NSString *)tableName :(NSDictionary *)valueMap;
 

Description:
Insert values into a table. Value map will contain the values to be inserted saved in a dictionary against the column names as keys.

Usage:

Code (objc)

[CMS_Database query_insert:<table_name> :<insert_map>];
 

Example:

Code (objc)

NSString *tableName = @"testTable";
NSDictionary *insertMap = @{
        @"field1":@"value11",
        @"field2":@"value12"
};
[CMS_Database query_insert:tableName :insertMap];
 
is equivalent to running INSERT INTO testTable (field1, field2) VALUES ('value11', 'value12');

query_select

Prototype:

Code (objc)

(NSArray *)query_select:(NSString *)tableName :(NSArray *)selectList :(NSDictionary *)whereMap :(NSString *)extraSQL;
 

Description:
Running a select query. "selectList" is the array of fields that needs to be selected. "whereMap" contains the conditions to be matched. Any extra SQL can be specified in "extraSQL".

Usage:

Code (objc)

[CMS_Database query_select:<table_name> :<selectFields> :<whereMap> :nil];
 

Example:

Code (objc)

NSString *tableName = @"testTable";
[CMS_Database query_select:tableName :@[@"field1"] :@{@"field2":@"value22"} :nil];
 
is equivalent to running SELECT field1 from testTable where field2='value22';

query_select_value

Prototype:

Code (objc)

(NSString *)query_select_value:(NSString *)tableName :(NSString *)selectFieldName :(NSDictionary *)whereMap :(NSString *)extraSQL;
 

Description:
Selecting a single string value from the database. If more than one rows are found in the result of the query, the value in the first row is returned. If no value, blank string will be returned.

Usage:

Code (objc)

[CMS_Database query_select_value:<table_name> :<selectField> :<whereMap> :nil];
 

query_select_int_value

Prototype:

Code (objc)

(int)query_select_int_value:(NSString *)tableName :(NSString *)selectFieldName :(NSDictionary *)whereMap :(NSString *)extraSQL;
 

Description:
Selecting a single integer value from the database. If more than one rows are found in the result of the query then the value in the first row is returned. If no value, -1 is returned. If the value was not an integer convertible, 0 is returned.

Usage:

Code (objc)

[CMS_Database query_select_int_value:<table_name> :<selectField> :<whereMap> :nil];
 

query_update

Prototype:

Code (objc)

(void)query_update:(NSString *)tableName :(NSDictionary *)valueMap :(NSDictionary *)whereMap;
 

Description:
Update rows in a table based on a particular condition. "valueMap" is Values to be updated in a map saved against field name as keys.

Usage:

Code (objc)

[CMS_Database query_update:<table_name> :<value_map> :<where_map>];
 

Example:

Code (objc)

NSString *tableName = @"testTable";
[CMS_Database query_update:tableName :@{@"field2":@"40"} :@{@"field1":@"value31"}];
 
is equivalent to executing UPDATE testTable SET field2='40' WHERE field1='value31';

getFieldNamesForTable

Prototype:

Code (objc)

+ (NSArray *) getFieldNamesForTable:(NSString *)tableName;
 

Description:
Get the list of column names of a table.

Usage:

Code (objc)

[CMS_Database getFieldNamesForTable:<table_name>];
 

upgradeDatabaseIfRequired

Prototype:

Code (objc)

(void)upgradeDatabaseIfRequired:(CMSDatabaseUpgradeBlock)upgradeBlock;
 

Description:
Upgrade the database using the code handler provided. The code handler receives a database object as a parameter so that you can execute your SQLite queries directly. The latest database version is saved in the NSUserDefaults so that your step by step upgrades will be executed. In short, we provide a convention (similar to in Composr) for progressive upgrading.

Usage:

Code (objc)

[CMS_Database upgradeDatabaseIfRequired:<upgrade_handler>];
 

Example:

Code (objc)

[CMS_Database upgradeDatabaseIfRequired:^(sqlite3 *dbInstance){
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSString *previousVersion = [defaults objectForKey:k_DBVERSION];
        NSString *currentVersion = [self versionNumberString];

        if (previousVersion==nil){
                // do nothing. first install.
        }
        else if([previousVersion compare:currentVersion options:NSNumericSearch] == NSOrderedAscending) {
                // previous < current
                // place upgrade codes here for each versions in their corresponding if structures.
                // You can use the "dbInstance" variable to access the db.

                int prevVersion = [previousVersion intValue];
                if (prevVersion < 1) {
                        // place all codes for upgrading to version 1
                        prevVersion = 1;
                }
                if (prevVersion < 2) {
                        // place all codes for upgrading to version 2
                        prevVersion = 2;
                }
        }
        [defaults setObject:currentVersion forKey:k_DBVERSION];
        [defaults synchronize];
}];
 

CMS_Notification

This class provides all the functions required to handle push notifications in an iPhone app. The functions are:

registerForRemoteNotifications

Prototype:

Code (objc)

(void)registerForRemoteNotifications;
 

Description:
Register the app for permission to push notifications.

Usage:

Code (objc)

[CMS_Notification registerForRemoteNotifications];
 

parseDeviceToken

Prototype:

Code (objc)

(NSString *)parseDeviceToken:(NSData *)deviceToken;
 

Description:
Parse the device token that has been received from the APNS server.

Usage:

Code (objc)

[CMS_Notification parseDeviceToken:<NSData received from the server that registered for remote notifications>
 

notifyDeviceTokenToServer

Prototype:

Code (objc)

(void) notifyDeviceTokenToServer:(NSString *)deviceToken;
 

Description:
Send the device token to the Composr website.

Usage:

Code (objc)

[CMS_Notification notifyDeviceTokenToServer:<parsed device token as string>];
 

showNotification

Prototype:

Code (objc)

(void) showNotification:(NSDictionary *)userInfo;
 

Description:
Parse a push notification received from the Composr server and show the alert.

Usage:

Code (objc)

[CMS_Notification showNotification:<payload received as notification>];
 

CMSNetworkManager

CMSNetworkManager is a singleton network manager that is built on AFNetworking 2.0. A JSON parser is mounted as the default response parser. So, if you need to parse any other kind of responses like XML, plain/text or so, you will need to modify the response serialiser.

The following APIs are already built into the CMSNetworkManager:
  1. Login
    1. The response received is saved in the NSUserDefaults
    2. Cookie and session variables are automatically set in the header of all the API calls after a successful login
  2. Register
  3. Recover Password
  4. Feedback/Contact Us
  5. Save push token to Composr Server

More APIs can be integrated as required. The above written API calls use a standard format. All the API functions have a completion handler attached and the CMSNetworkManager also has a delegate. If completion handler is available, the callback is executed using the completion handler. If the completion handler is nil, the delegate methods are called. The same case goes for failures too.

Initiating the CMSNetworkManager singleton class…

Initialize a generic network manager:

Code (objc)

[CMSNetworkManager sharedManager];
 

Initialize network manager with a specific base URL:

Code (objc)

[[CMSNetworkManager sharedManager] initWithBaseURL:<domain_url>];
 

The class has two generic API functions, one for GET, another for POST.

GET

Prototype:

Code (objc)

(void)executeGETWithParams:(NSDictionary *)params forURL:(NSString *)url onCompletion:(CMSResponseBlock)objectBlock onFaillure:(CMSErrorBlock)failBlock showLoader:(BOOL)showLoader;
 

Description:
Executes a GET request on the given URL:
  • params – map of parameters to be sent as key value pair along with URL
  • URL – URL to connect to
  • completion block
  • failure block
  • showLoader – should a loader be shown blocking the screen when executing the API call

Usage:

Code (objc)

[self executeGETWithParams:<params_map>
        forURL:<url>
                onCompletion:<completion handler>
                onFaillure:<failure_handler>
                showLoader:<show loader ?>];
 

POST

Prototype:

Code (objc)

(void)executePOSTWithParams:(NSDictionary *)params forURL:(NSString *)url onCompletion:(CMSResponseBlock)objectBlock onFaillure:(CMSErrorBlock)failBlock showLoader:(BOOL)showLoader
 

Description:
Executes a POST request on the given URL:
  • params – map of parameters to be sent as key value pair in body
  • URL – URL to connect to
  • completion block
  • failure block
  • showLoader – should a loader be shown blocking the screen when executing the API call

Usage:

Code (objc)

[self executePOSTWithParams:<params_map>
        forURL:<url>
                onCompletion:<completion handler>
                onFaillure:<failure_handler>
                showLoader:<show loader ?>];
 

Apart from this, the CMSNetworkManager has functions within it for parsing responses and error, from the Composr API calls. These are:
  1. isResponseValid – if passed a response, it returns TRUE or FALSE
  2. getResponseData – if passed a response, it returns the JSON response's response_data as a map, or an empty map on error
  3. getError – if passed a response, it returns an NSError

More Utilities

Composr Mobile SDK contains some custom generic utility views that are used within the form builder. These functions can be reused separately if required. They are:

NumberInput

Number-only entry text field.

Usage:

Code (objc)

NumberInput *txtInput = [[NumberInput alloc] initWithFrame:<frame> defaultValue:<default_value> placeHolder:<placeholder> supportFloat:<support floating point?>];
 

ComboBox

Textfield linked with a picker automatically.

Usage:

Code (objc)

ComboBox *txtInput = [[ComboBox alloc] initWithFrame:<frame>];[txtInput setOptions:<values of options>];[txtInput setKeys:<the param name or key of options>];[txtInput setDefaultValue:<default value to be selected>];
 

DatePicker

Textfield linked to a date picker automatically.

Usage:

Code (objc)

DatePicker *txtInput = [[DatePicker alloc] initDatePickerWithTime:includeTimeChoice frame:<frame>];
 

PhotoUpload

A control that acts as a photo upload form control by itself. Has option to take image from photo gallery as well as the camera.

Usage:

Code (objc)

PhotoUpload *photoView = [[PhotoUpload alloc] initWithFrame:<frame>];[photoView setImage:<a no image placeholder image>];
 

Notifications

Composr can support sending native iOS/Android push notifications.

There are many configuration options located in Admin Zone > Setup > Configuration > Composr API options.

For iOS notifications to work, put your Apple-provided server certificate over data_custom/modules/composr_mobile_sdk/ios/server_certificates.pem (follow the usual CSR signing process against your Apple developer account).

Toolkit

The toolkit will help you mirror some Composr website resources into a mobile app. It is a part of the non-bundled composr_mobile_sdk addon.

Language files

This tool will generate iOS/Android string resources.

It is approximate. For example, it does not handle the data types and pluralisation that Android can support or data types that iOS can support.

  1. Open a command prompt to the Composr installation directory.
  2. Type a command like:

    Code (Bash)

    php data_custom/composr_mobile_sdk_build.php language <the .ini filenames which needs to be parsed separated by spaces> <language name>
     
    For example, to export the polls.ini and galleries.ini files from the EN language pack:

    Code (Bash)

    php data_custom/composr_mobile_sdk_build.php language polls galleries EN
     
  3. Find the files have been generated under exports/composr_mobile_sdk
  4. Copy through to your app, hand-editing as required

Image assets

This tool will export theme images to a directory structure more appropriate for copying directly into an iOS/Android app as image assets.

  1. Open a command prompt to the Composr installation directory.
  2. Type a command like:

    Code (Bash)

    php data_custom/composr_mobile_sdk_build.php images <theme>
     
    For example, to export the example theme:

    Code (Bash)

    php data_custom/composr_mobile_sdk_build.php images example
     
  3. Find the files have been generated under exports/composr_mobile_sdk/image_assets
  4. Delete assets you don't want them copy through to your app

Server-side API

You may access the server-side API by making HTTP calls to http://yourbaseurl/data/endpoint.php. Results are returned as JSON.

The API is split into a number of endpoints, which are given a 'hook' name, and categorised by 'hook type'.

Both REST-style and GET-parameter style requests can be made. As most calls are not really content-based (they are functional-based), REST isn't necessarily relevant as a metaphor, so we recommend keeping it simple and just using the GET-parameter method in most cases.

Here are 2 equivalent example API calls…
  • PUT http://yourbaseurl/data/endpoint.php/somehooktype/somehook/someid (REST style)
  • POST http://yourbaseurl/data/endpoint.php?hook_type=somehooktype&hook=somehook&type=edit&id=someid (GET-parameter style)
Notice these differences:
  1. Request method vs simple GET/POST with use of Composr-style type parameter.
    They are mapped as follows: GET=view, PUT=edit, POST=add, DELETE=delete.
  2. The path components after the PHP file, vs use of hook_type, hook, and id GET parameters.

Apart from the standardised type and id request parameters described above, input parameters are just put through as GET/POST parameters (i.e. not submitted via POSTed/PUT JSON data). Different endpoints may use different parameters. It is up to the endpoint how to use the parameters, even the meaning of type and id is not defined and those parameters are not required by all endpoints.

JSON is returned in the response as a structure like:

Code (JavaScript)

{
        success: true|false,
        error_details: string|null,
        response_data: ...
}
 

Any endpoint may return an error as a false success, so the iOS/Android code must handle this. If there is an error, error_details will always be set. Error messages are guaranteed to be human-readable and to be translatable, so you can show them directly to mobile users.

The particular data returned within response_data varies by endpoint.

Authentication is done automatically using cookies, just like it would for normal website requests. If you can't use cookies, re-send the device_auth_member_id_cn/device_auth_pass_hashed_cn/device_auth_member_id_vl/device_auth_pass_hashed_vl response parameters from the login endpoint as POST parameters to subsequent requests.

Default available endpoints

Hook type Hook GET parameters POST parameters Dictionary entries within response_data
account join None Whatever the normal Composr join form POSTS through. This is usually at least:
username

password

password_confirm

email_address

email_address_confirm

dob_day

dob_month

dob_year
message
account login None username

password
device_auth_member_id_cn (name of cookie containing member ID)

device_auth_pass_hashed_cn (name of cookie containing hashed password)

device_auth_member_id_vl (member ID, if reading cookies is too difficult on your platform)

device_auth_pass_hashed_vl (hashed password, if reading cookies is too difficult on your platform)

Lots of data from Composr's cns_read_in_member_profile function
account lost_password username (optional)

email_address (optional) – one of these must be passed
None message
account setup_push_notifications device ("ios" or "android")

member (optional, the member ID being set up for – defaults to current member)
token (device notification token) message
misc contact_us None category (optional, category for message)

post (the message)

title (optional, the subject line)

email (optional, the e-mail to send from – defaults to that of current member)
message
content commandr_fs None

The standardised type specifies the REST operation

The standardised id specifies the Commandr-fs path
Raw data, not split into fields

or

A single parameter named data containing said data
Whatever the Commandr-fs hook has

You may want to install a browser extension such as JSONView when developing with the API. Mozilla Firefox has great JSON viewing built-in.

Other approaches to mobile integration

On the tracker you will find a number of plans and issues relating to further development of Composr Mobile SDK. This is an active process, as we move forward a number of complementary alternative approaches, suited for different mobile integration/extension scenarios. As with all Composr development, development is primary implemented as a byproduct of commercial projects or direct feature sponsorship, but guided by a shared plan that benefits all interested users.

Tapatalk

There is an official Composr addon (non-bundled) for implementing Tapatalk support for Composr. Tapatalk is a third party forum app for smartphones that can connect to your own forum, providing a high-quality experience to users. Tapatalk will essentially function as an "out of the box Composr app", as we continue to extend our Tapatalk implementation to include other kinds of content within virtual-forums/virtual-topics.


See also


Feedback

Please rate this tutorial:

Have a suggestion? Report an issue on the tracker.