Skip to end of metadata
Go to start of metadata

IOS SDK Integration Guide - CM

 

Version 1.2.7

This is Phunware's iOS SDK README for the Content Management module. Visit http://maas.phunware.com/ for more details and to sign up.

Requirements

  • MaaS Core v1.3.0 or greater
  • iOS 6.0 or greater
  • Xcode 6 or greater

Getting Started

Installation

The following frameworks are required:

MaaSCore.framework

MaaS Content Management has a dependency on MaaSCore.framework, which is available here: Core SDK (iOS)

It's recommended that you add the MaaS frameworks to the 'Vendor/Phunware' directory. This directory should contain MaaSCore.framework and MaaSCMS.framework as well as any other MaaS frameworks that you are using.

Documentation

Documentation is included in the Documents folder in the repository as both HTML and as a .docset. You can also find the latest documentation here: CM API iOS Reference

Overview

The MaaS Content Management SDK allows developers to fetch and manage the various pieces of data in the Content Management module, including containers, schemas, structure and content. Content Management spans across your entire organization, so different applications can potentially share the same content.

Container

Containers hold a single structure. You can create any number of containers in the MaaS portal. You can also associate tags with containers to assist with fetching.

Schema

Schemas are applied to structure items and define what fields of data a particular structure item can contain. You can create any number of schemas in the MaaS portal. You can also associate tags with schemas to assist with fetching.

Structure

Structure items are used to build the structure and hierarchy of the data. Each structure item that is defined as an object can also optionally be assigned a schema that defines what content can be saved to structure items.

Content

The structure of the content object relies completely on the structure of the menus and schemas.

Integration

The primary methods in Content Management revolve fetching, creating, updating and deleting content. You can also GET structures, containers and schemas.

Getting Content

	// Get a specific piece of content for the specified content ID, container ID and structure ID. The contents are always returned as an NSDictionary object. It's recommended that you parse the dictionary into a model object.
    [MaaSCMS getContentForContentID:@"CONTENT_ID" containerID:@"CONTAINER_ID" structureID:123 success:^(NSDictionary *content) {
        ...
    } failure:^(NSError *error) {
        ...
    }];

Updating Content

	// Update content for the specified content ID, container ID and structure ID. Any omitted fields will maintain their previous values.
    NSDictionary *updatedContent = @{@"user_name" : @"MaaS Test User"};
    
    [MaaSCMS updateContentForContentID:@"CONTENT_ID" containerID:@"CONTAINER_ID" structureID:123 updatedContent:updatedContent success:^{
        ...
    } failure:^(NSError *error) {
        ...
    }];

Creating Content

	// Add content to the specified container ID, structure ID and parent content ID. Ideally, the new content dictionary has all the fields as specified by the structure and schema. If not, the required fields will be created for you with empty values.
    NSDictionary *newContent = @{@"user_name" : @"MaaS Test User"};
    
    [MaaSCMS addContent:newContent containerID:@"CONTAINER_ID" structureID:123 parentContentID:@"PARENT_CONTENT_ID" success:^(NSString *newContentID) {
        ...
    } failure:^(NSError *error) {
        ...
    }]; 

Deleting Content

	// Delete content for the specified content ID, as well as all content children.
    [MaaSCMS deleteContentForContentID:@"CONTENT_ID" traverse:YES success:^{
        ...
    } failure:^(NSError *error) {
        ...
    }];
    
    // Delete all content children for the specified content ID.
    [MaaSCMS deleteContentChildrenForContentID:@"CONTENT_ID" success:^{
        ...
    } failure:^(NSError *error) {
        ...
    }];

Containers

	// Fetch all containers.
    [MaaSCMS getAllContainersWithSuccess:^(NSArray *containers) {
        ...
    } failure:^(NSError *error) {
        ...
    }];
    
    // Fetch a specific container item.
    [MaaSCMS getContainerWithContainerID:@"CONTAINER_ID" success:^(PWContainer *container) {
        ...
    } failure:^(NSError *error) {
        ...
    }];
    
    // Get an array of containers that match an array of tags.
    [MaaSCMS getContainersContainingAnyTags:@[@"CONTAINER_TAG"] containingAllTags:nil success:^(NSArray *containers) {
        ...
    } failure:^(NSError *error) {
        ...
    }];

Schemas

	// Fetch all schemas.
    [MaaSCMS getAllSchemasWithSuccess:^(NSArray *schemas) {
        ...
    } failure:^(NSError *error) {
        ...
    }];
    
    // Fetch a specific schema item.
    [MaaSCMS getSchemaWithSchemaID:@"SCHEMA_ID" success:^(PWSchema *schema) {
        ...
    } failure:^(NSError *error) {
        ...
    }];
    
    // Get an array of schemas with the specificed pagination parameters
    [MaaSCMS getSchemasWithLimit:10 offset:0 success:^(NSArray *schemas, PWPagination *pagination, BOOL pagingEnabled) {
        ...
    } failure:^(NSError *error) {
        ...
    }];

Structure

	// Fetch a specific structure item with the specified stucture and container ID. In this example, we want to traverse into all child structures and exclude schemata.
    [MaaSCMS getStructureWithID:123 containerID:@"CONTAINER_ID" depth:kMaaSCMSDepthFullHierarchy includeSchema:NO success:^(PWStructure *structure) {
        ...
    } failure:^(NSError *error) {
        ...
    }];
    
    // Get an array of structures for the specified container ID. In this example, we want to traverse into all child structures and include schemata.
    [MaaSCMS getStructuresForContainerID:@"CONTAINER_ID" depth:kMaaSCMSDepthFullHierarchy includeSchema:YES success:^(NSArray *structures) {
        ...
    } failure:^(NSError *error) {
        ...
    }];

ON THIS PAGE

iOS SDK Content Creation and Updates - CM

 

- (void)saveRecord:(PWCMERecord *)record
 completionHandler:(void (^)(PWCMERecord *record, NSError *error))completionHandler;

This method creates a new record or updates an existing record if an ID of record is specified.

This method saves the record with a default priority, which may cause the task to execute after higher-priority tasks. To save records more urgently, create a PWCMEModifyRecordsOperation object with the desired priority. You can also use that operation object to save multiple records simultaneously.

Parameters

record – The record to save. You can create a new record or update an existing one if you specify its ID. An exception is thrown if this parameter is nil.

completionHandler – The block to execute with the results. Your block must be capable of running on any thread of the app and must take the following parameters: - record: The record object you attempted to save. - error: An error object or nil if the record was saved successfully. Use the information in the error object to determine whether a problem has a workaround.

Sample Code

PWCMERecordID *recordID = [[PWCMERecordID alloc] initWithStructureID:xxx parentIdentifier:nil];
PWCMERecord *record = [[PWCMERecord alloc] initWithRecordID:recordID];
record[@"firstName"] = @"John";
record[@"lastName"] = @"Smith";
record[@"title"] = @"President";
record[@"office"] = @"San Diego";
[[PWCMEContainer defaultContainer] saveRecord:record
                            completionHandler:^(PWCMERecord *record, NSError *error) {
    if (!error) {
        // The record was successfully created.
    }
    else {
        // Something went wrong. Be sure to handle the error!
        NSLog(@"Error: %@", error.debugDescription);
    }
}]; 

ON THIS PAGE

iOS SDK Fetching Content - CM

 

- (void)fetchRecordWithID:(PWCMERecordID *)recordID
        completionHandler:(void (^)(PWCMERecord *record, NSError *error))completionHandler 

This method fetches the record with a default priority, which may cause the task to execute after higher-priority tasks. If you want to fetch records more urgently, create a PWCMEFetchRecordsOperation object with the desired priority. You can also use that operation object to fetch multiple records simultaneously.

Parameters

recordID – The ID of the record you want to fetch. An exception is thrown if this parameter is nil.

completionHandler – The block to execute with the results. Your block must be capable of running on any thread of the app and must take the following parameters:

  • record: The requested record object. If no such record is found, this parameter is nil.

  • error: An error object, or nil if the record was fetched successfully. Use the information in the error object to determine whether a problem has a workaround.

Sample Code

PWCMERecordID *recordID = ...;
[[PWCMEContainer defaultContainer] fetchRecordWithID:recordID
                                   completionHandler:^(PWCMERecord *record, NSError *error) {
    if (!error) {
        // Use the record.
    }
    else {
        // Something went wrong. Be sure to handle the error!
        NSLog(@"Error: %@", error.debugDescription);
    }
}]; 

ON THIS PAGE

iOS SDK Deleting Content - CM

 

- (void)deleteRecordWithID:(PWCMERecordID *)recordID
         completionHandler:(void (^)(PWCMERecordID *recordID, NSError *error))completionHandler;

Deleting a record may trigger additional deletions if the record was referenced by other records. This method reports only the ID of the record you asked to delete. PWCME does not report deletions triggered by owning relationships between records.

This method deletes the record with a default priority, which may cause the task to execute after higher-priority tasks. If you want to delete records more urgently, create a PWCMEModifyRecordsOperation object with the desired priority. You can also use that operation object to delete multiple records simultaneously.

Parameters

recordID – The ID of the record you want to delete. An exception is thrown if this parameter is nil.

completionHandler – The block to execute with the results. Your block must be capable of running on any thread of the app and must take the following parameters:

  • recordID: The record ID you attempted to delete. If no such record is found, this parameter is nil.

  • error: An error object or nil if the record was fetched successfully. Use the information in the error object to determine whether a problem has a workaround.

Sample Code

PWCMERecordID *recordID = ...;
[[PWCMEContainer defaultContainer] deleteRecordWithID:recordID
                                    completionHandler:^(PWCMERecordID *recordID, NSError *error) {
    if (!error) {
        // The record was successfully deleted.
    }
    else {
        // Something went wrong. Be sure to handle the error!
        NSLog(@"Error: %@", error.debugDescription);
    }
}];

ON THIS PAGE

iOS SDK Querying Content - CM

 

The PWCME SDK provides convenient methods that allow you to very easily search and filter for CME content. The primary classes for querying are PWCMEQuery and PWCMEQueryOperation. You can also leverage the convenience method on PWCMEContainer to perform queries.

Constructing a Query

Constructing a query takes just a few steps.

1. Create an NSPredicate.

NSComparisonPredicate *predicate1 = [NSComparisonPredicate predicateWithFormat:@"title LIKE 'engineer'"];
NSComparisonPredicate *predicate2 = [NSComparisonPredicate predicateWithFormat:@"location IN { 'Austin' }"];
NSCompoundPredicate *compound = [[NSCompoundPredicate alloc] initWithType:NSOrPredicateType 
                                subpredicates:@[predicate1, predicate2]];

2. Initialize your PWCMEQuery object with the predicate.

PWCMEQuery *query = [[PWCMEQuery alloc] initWithFieldName:@"people" predicate:compound]; 

3. Customize your query parameters (such as sorting and desired keys).

query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"createdAt" ascending:YES]];
query.desiredKeys = @[@"firstName", @"lastName"]; 

Executing a Query

There are two ways of executing a query.

Execute a query against a PWCMEContainer:

[[PWCMEContainer defaultContainer] performQuery:query 
			      completionHandler:^(NSArray *records, NSError *error) {
    if (!error) {
        // Process the records.
    }
    else {
        // Failed to delete a record; handle the error.
        NSLog(@"Error: %@", error.debugDescription);
    }
}];
Do not use this method when the number of returned records is potentially more than 100 records; for efficiency, all queries automatically limit the number of returned records based on current conditions. If your query hits the maximum value, this method returns only the first portion of the overall results. The number of returned records should be sufficient in most cases, but to get the entire set of records you must use a PWCMEQueryOperation object instead. Query operations also return a maximum number of results, but when they do, they provide a cursor object that you can use to fetch the next batch of results.

Execute a query using PWCMEQueryOperation:

PWCMEQueryOperation *operation = [[PWCMEQueryOperation alloc] initWithQuery:query];
[operation setQueryCompletionBlock:^(NSArray *records, PWCMEQueryCursor *cursor, NSError *error) {
    // Handle response.
}];

[[PWCMEContainer defaultContainer] addOperation:operation]; 

Paging Query Responses

The results of your query may be larger than your current resultsLimit. If this is the case, a PWCMEQueryCursor object will be returned. You can use the cursor to initialize another PWCMEQueryOperation to fetch additional records:

PWCMEQueryOperation *operation = [[PWCMEQueryOperation alloc] initWithCursor:cursor];
[operation setQueryCompletionBlock:^(NSArray *records, PWCMEQueryCursor *cursor, NSError *error) {
    // Handle response
}];

[[PWCMEContainer defaultContainer] addOperation:operation];

ON THIS PAGE

iOS SDK Building Query Predicates - CM

 

An NSPredicate object defines the logical conditions for determining whether a record is a match for a query. The PWCMEQuery class supports a subset of the predicate behaviors offered by the full NSPredicate class.

Predicate Rules for Query Objects

The predicates you create for your query objects must follow these rules:

  • Predicates are based on a format string. You cannot use value- or block-based predicates. 
  • Predicates use only the operators listed in the "Supported Predicate Operators" table below. 
  • Predicates operate only on fields containing the following types of data: 
    • NSString 
    • NSDate 
    • NSNumber 
  • Key names used in predicates correspond to fields in the currently evaluated record. Key names may include the names of the record’s metadata properties such as "creationDate” or any data fields you added to the record. You cannot use key paths to specify fields in related records. 
  • Predicates support the following variable substitution strings: 
    • Use %@ for value objects such as strings, numbers and dates. 
    • Use %K for the name of a field. This substitution variable indicates that the substituted string should be used to look up a field name. 
  • BETWEEN queries are not currently supported.

Supported Predicate Operators

OperationSupported Operators
Basic comparisons=, ==, >=, =>, <=, =<, <, >!=, <>
Basic compound predicates

AND, &&
NOT

String comparisonsBEGINSWITH
Aggregate operationsIN
CONTAINS
Regular expressionsMATCHES

Specifying an unsupported operator or data type in your query’s predicate results in a silent error when you execute the query.

Sample Predicate Format Strings

Matching a Field to a Specific Value

To match the contents of a field to a specific value, use a predicate similar to the ones shown below. All of the listed predicates generate the same set of results, which in the example means that the "favoriteColors" field contains the value "red". The value in the field must match the value you specify in the predicate exactly. String-based comparisons are case insensitive, but otherwise all comparisons must be an exact match of the specified value.

NSPredicate *predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"ANY favoriteColors = 'red'"];
predicate = [NSPredicate predicateWithFormat:@"favoriteColors CONTAINS 'red'"];
predicate = [NSPredicate predicateWithFormat:@"'red' IN favoriteColors"];
predicate = [NSPredicate predicateWithFormat:@"%K CONTAINS %@", @"favoriteColors", @"red"]; 

Matching a Field to One or More Values

You can match against more than one value at a time by using a predicate similar to the ones below. In the example, the predicates report a match if the value in the "favoriteColor" field of a record matches either of the values "red" or "green".

NSPredicate *predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"ANY { 'red', 'green' } = favoriteColor"];
predicate = [NSPredicate predicateWithFormat:@"favoriteColor IN { 'red', 'green' }"]; 

Matching a Field That Starts with a String Value

For fields that contain string values, you can match the beginning portion of the string using the BEGINSWITH or CONTAINS operator as shown below. Currently, you cannot use other string comparison operators such ENDSWITH. When using this operator, the field must contain a string value and must start with the string you specified. Matches are NOT case insensitive. In the examples, the predicate matches records whose "favoriteColors" field contained the strings "red", "reddish" or "red green duct tape".

NSString *matchString = @"red";
NSPredicate predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"ANY favoriteColors BEGINSWITH 'red'"]
predicate = [NSPredicate predicateWithFormat:@"ANY favoriteColors BEGINSWITH %@", matchString]
predicate = [NSPredicate predicateWithFormat:@"ANY favoriteColors CONTAINS 'red'"]
predicate = [NSPredicate predicateWithFormat:@"ANY favoriteColors CONTAINS %@", matchString] 

Matching a Field Containing a Tokenized String

To perform a tokenized search of a record’s fields, use the special operator self. A tokenized search searches any fields that have full-text search enabled, which are all string-based fields by default. Below is an example that searches the fields of the record for the token strings "bob" and "smith". Each distinct word is treated as a separate token for the purpose of searching. Comparisons are case- and diacritic-insensitive. These token strings may be found in single or multiple fields, but all of the tokens must be present in a record for it to be considered a match.

NSPredicate *predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS 'bob smith'"] 

Matching a Field with Regular Expressions

To perform a search with regular expressions, use the MATCHES operator.

NSPredicate *predicate = nil;
predicate = [NSPredicate predicateWithFormat:@"emailID MATCHES 'phunware^'"] 

ON THIS PAGE

  • No labels