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
-
Composr Tutorial: Mobile apps via Composr Mobile SDK
- Getting Composr Mobile SDK
- Setup
-
Using Composr Mobile SDK
- CMS_Arrays
- CMS_Strings
- CMS_Langs
- CMS_Preferences
- CMS_Timestamps
- CMS_HTTP
- CMS_Users
- CMS_Flow
-
CMS_Forms
- form_input_field_spacer_withHeading
- form_input_hidden_withParamName
- form_input_integer_withPrettyName
- form_input_float_withPrettyName
- form_input_line_withPrettyName
- form_input_password_withPrettyName
- form_input_list_withPrettyName
- form_input_text_withPrettyName
- form_input_tick_withPrettyName
- form_input_uploaded_picture_withPrettyName
- form_input_date_withPrettyName
- get_input_date
- post_param_string
- post_param_integer
- set_url
- set_button_withName
- do_http_post_request
- getFormValues
-
CMS_Database
- createCopyOfDatabaseIfNeeded
- initializeDatabase
- create_table
- drop_table_if_exists
- add_table_field
- rename_table_field
- delete_table_field
- db_escape_string
- query
- query_delete
- query_insert
- query_select
- query_select_value
- query_select_int_value
- query_update
- getFieldNamesForTable
- upgradeDatabaseIfRequired
- CMS_Notification
- CMSNetworkManager
- More Utilities
- Notifications
- Toolkit
- Server-side API
- Other approaches to mobile integration
- 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:- Create a new project to use with CMS_SDK or open an existing project.
- 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
- 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
- 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".
- 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
- 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.
- 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.
- Now, open up your pch file and import CMS_SDK.h so that the SDK is available in your entire project.
Android
How to link the SDK into your project, assuming you are using Eclipse:- Create a new project to use with CMS_SDK, or open an existing project
- Import CMS_SDK into your workspace as an android project
- Open the "Properties" of CMS_SDK and make sure "is Library" is checked under the "Android" tab
- 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.
- 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: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:
collapse_2d_complexity
Prototype:Code (objc)
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.
[CMS_Arrays collapse_2d_complexity:inputKeyKey :inputKeyVal:inputArray];
… you would get a dictionary of the following form:
Code (objc)
@{
@"1" : @"Belgium",
@"2" : @"France"
};
@"1" : @"Belgium",
@"2" : @"France"
};
explode
Prototype: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.
Calling [CMS_Arrays explode:separator :source]; will return an array of strings:
Code (objc)
@[@"This",@"is",@"an",@"example",@"string"];
implode
Prototype: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.
Calling [CMS_Arrays implode:joiner :source]; will return a single string:
Code (objc)
@"This-is-an-example-string"
list_to_map
Prototype:Code (objc)
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"
}
];
@{
@"key1":@"valA1",
@"key2":@"valA2"
},
@{
@"key1":@"valB1",
@"key2":@"valB2"
}
];
Code (objc)
@{
@"valA1":@{
@"key1":@"valA1",
@"key2":@"valA2"
}
},
@{
@"valB1":@{
@"key1":@"valB1",
@"key2":@"valB2"
}
}
@"valA1":@{
@"key1":@"valA1",
@"key2":@"valA2"
}
},
@{
@"valB1":@{
@"key1":@"valB1",
@"key2":@"valB2"
}
}
array_values
Prototype:Code (objc)
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)
Code (objc)
@[@"key1",@"key2"]
Code (objc)
@[@"val1",@"val2"]
array_merge
Prototype: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)
@[@1, @2, @"3", @"test", @5.3, @6, @2, @"fdfd"]
sort
Prototype:Code (objc)
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)
Code (objc)
@[@"-1", @0, @"1", @4]
array_key_exists
Prototype:Code (objc)
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)
Calling [CMS_Arrays array_key_exists:@"3.6" :inputMap]; will return true.
array_unique
Prototype: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)
Code (objc)
@[@1, @2, @"3", @"test", @5.3]
sort_maps_by
Prototype: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"
}
];
@{
@"id":@1,
@"val":@"val5"
},
@{
@"id":@3,
@"val":@"val2"
},
@{
@"id":@0,
@"val":@"Val9"
}
];
Code (objc)
@[
@{
@"id":@0,
@"val":@"Val9"
},
@{
@"id":@1,
@"val":@"val5"
},
@{
@"id":@3,
@"val":@"val2"
}
]
@{
@"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)
Code (objc)
NSDictionary *map = @{
@"key1":@"val1",
@"key2":@"val2",
@"key3":@"val3",
@"key4":@"val4",
@"key5":@"val5"
};
@"key1":@"val1",
@"key2":@"val2",
@"key3":@"val3",
@"key4":@"val4",
@"key5":@"val5"
};
list_to_map
Prototype:Code (objc)
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"
}
];
@{
@"id" : @"1",
@"val" : @"val1"
},
@{
@"id" : @"2",
@"val" : @"val2"
},
@{
@"id" : @"3",
@"val" : @"val3"
}
];
Code (objc)
@{
@"1" : @{
@"id" : @"1",
@"val" : @"val1"
},
@"2" : @{
@"id" : @"2",
@"val" : @"val2"
},
@"3" : @{
@"id" : @"3",
@"val" : @"val3"
}
};
@"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: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)
Code (objc)
@"Hi. How are you?"
html_entity_decode
Prototype:Description:
Convert the common HTML entity into standard keyboard characters. For example, the entity & 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)
Code (objc)
@"\"I love cats & dogs\"".
float_format
Prototype:Code (objc)
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 :YES] will return @"12,345,678"
[CMS_Strings float_format:input :2 :YES] will return @"12,345,678.01"
strpos
Prototype: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: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: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: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: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:Description:
To get the length of a string, the strlen function can be used.
Usage:
Code (objc)
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: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: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:Description:
Get the default value from NSUserDefaults.
Usage:
Code (objc)
[CMS_Preferences get_value:<key>]
set_value
Prototype: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)
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)
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)
Description:
Returns the UNIX timestamp.
Usage:
Code (objc)
CMS_HTTP
The CMS_HTTP class provides functions needed while connecting and parsing web services. This class contains the following functions:rawurlencode
Prototype: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)
Code (objc)
@"test%20encoding%20the%20url%20%2B%20something"
json_decode
Prototype:Code (objc)
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)
Code (objc)
@{
@"test" : @"val",
@"test1" : @"val1"
};
@"test" : @"val",
@"test1" : @"val1"
};
json_encode
Prototype:Code (objc)
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)
Code (objc)
@"{\"test\":\"val\",\"test1\":\"val1\"}"
get_base_url
Prototype:Code (objc)
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)
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?¶m1=value1¶m2=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);
}];
NSLog(@"%@",response);
}];
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)
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)
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)
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)
Description:
Returns the username of logged in user.
Usage:
Code (objc)
[CMS_Users get_username]
get_members_groups
Prototype:Code (objc)
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)
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)
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)
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)
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)
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];
[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:Description:
Adds a heading into the form.
Usage:
Code (objc)
[form_instance form_input_field_spacer_withHeading:<heading text>withText:<sub_heading text>];
Prototype: form_input_hidden_withParamName
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: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 ?>];
withDescription:<description>
withParamName:<param_name>
withDefaultValue:<default_value>
isRequired:<is_required ?>];
form_input_float_withPrettyName
Prototype: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 ?>];
withDescription:<description>
withParamName:<param_name>
withDefaultValue:<default_value>
isRequired:<is_required ?>];
form_input_line_withPrettyName
Prototype: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 ?>];
withDescription:<description>
withParamName:<param_name>
withDefaultValue:<default_value>
isRequired:<is_required ?>];
form_input_password_withPrettyName
Prototype: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 ?>];
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 ?>];
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];
withDescription:@"Gender"
withParamName:@"gender"
withOptions:@{
@"male":@"Male",
@"female":@"Female",
@"other":@"Other"
}
withDefaultValue:@"male"
isRequired:YES];
form_input_text_withPrettyName
Prototype: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 ?>];
withDescription:<description>
withParamName:<param_name>
withDefaultValue:<default_value>
isRequired:<is_required ?>];
form_input_tick_withPrettyName
Prototype: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>];
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];
withDescription:@""
withParamName:@"subscribe"
withDefaultValue:NO];
form_input_uploaded_picture_withPrettyName
Prototype: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 ?>];
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];
withDescription:@"upload your profile pic"
withParamName:@"profilePic"
isRequired:YES];
form_input_date_withPrettyName
Prototype: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 ?>];
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];
withDescription:@"Provide your DOB :"
withParamName:@"dob"
isRequired:YES
withDefaultValue:@""
includeTimeChoice:NO];
get_input_date
Prototype:Code (objc)
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"];
post_param_string
Prototype: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)
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)
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 ?>];
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];
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)
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: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:
drop_table_if_exists
Prototype:Code (objc)
Description:
Delete a table.
Usage:
Code (objc)
[CMS_Database drop_table_if_exists:<table_name>];
add_table_field
Prototype:Description:
Adds a new column to the table.
Usage:
Code (objc)
[CMS_Database add_table_field:<table_name> :<field_name>];
rename_table_field
Prototype: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:Description:
Delete a column from the table.
Usage:
Code (objc)
[CMS_Database delete_table_field:<table_name> :<delete_field_name>];
db_escape_string
Prototype: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: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)
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];
NSDictionary *deleteWhereMap = @{
@"field2":@"value22"
};
[CMS_Database query_delete:tableName :deleteWhereMap];
[CMS_Database query_delete:tableName :deleteWhereMap];
is equivalent to running - DELETE FROM testTable WHERE field2='value22';
query_insert
Prototype:Code (objc)
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];
NSDictionary *insertMap = @{
@"field1":@"value11",
@"field2":@"value12"
};
[CMS_Database query_insert:tableName :insertMap];
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];
[CMS_Database query_select:tableName :@[@"field1"] :@{@"field2":@"value22"} :nil];
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)
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"}];
[CMS_Database query_update:tableName :@{@"field2":@"40"} :@{@"field1":@"value31"}];
getFieldNamesForTable
Prototype: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];
}];
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: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)
Description:
Send the device token to the Composr website.
Usage:
Code (objc)
[CMS_Notification notifyDeviceTokenToServer:<parsed device token as string>];
showNotification
Prototype:Code (objc)
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:
- Login
- The response received is saved in the NSUserDefaults
- Cookie and session variables are automatically set in the header of all the API calls after a successful login
- Register
- Recover Password
- Feedback/Contact Us
- 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 ?>];
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 ?>];
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:
- isResponseValid – if passed a response, it returns TRUE or FALSE
- getResponseData – if passed a response, it returns the JSON response's response_data as a map, or an empty map on error
- 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.
- Open a command prompt to the Composr installation directory.
- 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>
Code (Bash)
php data_custom/composr_mobile_sdk_build.php language polls galleries EN
- Find the files have been generated under exports/composr_mobile_sdk
- 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.- Open a command prompt to the Composr installation directory.
- Type a command like:
Code (Bash)
php data_custom/composr_mobile_sdk_build.php images <theme>
Code (Bash)
php data_custom/composr_mobile_sdk_build.php images example
- Find the files have been generated under exports/composr_mobile_sdk/image_assets
- 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)
- 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. - 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: ...
}
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.Concepts
- SDK
- Software Development Kit. An implementation of an API, typically in the form of a library.
- Composr Mobile SDK
- Official toolkit for mobile apps that connect to a Composr-powered website. The name may be shortened to CMS SDK. CMS SDK is a set of libraries for Composr, Android, and iOS.
- Objective-C
- The main programming language used for programming Apple devices. Swift was released around the time of us writing CMS SDK, but we have used Objective-C to be conservative – both are cross-compatible, so there's no compatibility problems.
- REST
- A read/write convention/protocol implemented in terms of standard HTTP web calls.
- JSON
- JavaScript object notation, a common language for transferring structured data over REST
- Push notification
- A notification sent to a mobile device
See also
Feedback
Please rate this tutorial:
Have a suggestion? Report an issue on the tracker.