SimpleSample-customObjects-ios

Ask tech team
From QuickBlox Developers (API docs, code samples, SDK)
Jump to: navigation, search

Contents

Sources

Project homepage on GIT — https://github.com/QuickBlox/quickblox-ios-sdk/tree/master/sample-custom-objects

Download ZIP - https://github.com/QuickBlox/quickblox-ios-sdk/archive/master.zip


Overview

This sample demonstrates how to work with Custom Objects QuickBlox API.
It allows you to create any server side data structure, use it as you want, create any logic and a lot of other custom features.

It shows how to:

  1. Create your own server data structure & use it. In our example we created a data structure, that represents a simple Note.
  2. Get, Create, Update and Delete your data using a lot of filters.




Guide: Getting Started with Custom Objects API

Getting a QuickBlox account

http://admin.quickblox.com/register

Creating applications on the Admin panel

http://admin.quickblox.com/apps/new

In addition we have this useful 5 minute guide.

Connecting QuickBlox to your application

To get the information on how to connect to the QuickBlox.framework, please, refer to the IOS-how-to-connect-Quickblox-framework page.

Adding a Custom Data structure to your application

Note: This guide based on Custom Objects REST API documentation. It is very helpful, describes the full list of QuickBlox Custom Objects API features and need to be read in addition to reading this guide.

To start using the Custom Objects module you should create your data scheme. Go to admin.quickblox.com, find the Custom Objects module page and press the Add new class button. The 'add new class' popup will then appear.

Enter Class name, add fields any you want. Allow 7 types of fields:

  • Integer
  • Float
  • Boolean (true/false)
  • String
  • File
  • Location
  • Array (of Integers, Floats, Booleans, Strings)

COCreateClass.png

Press the Create class button and a new class will be created

COPredefinedFields.png

There are some predefined fields, that are described in this Custom Objects REST API Module description documentation.


Create a record

There are 2 ways to create a record:

  • through the Admin panel
  • using the iOS SDK


Create record through Admin panel

Just go to admin.quickblox.com, find the Custom Objects module page and press the Add record button. The 'add new record' popup will then appear. Fill in any fields you want and press the Add record button again. The new record will then be added & shown in the table.


Create record using iOS SDK

In order to create records you must be logged in and to act on a user's behalf - please refer to iOS Users API documentation.

To create a record just use the code below:

QBCOCustomObject *object = [QBCOCustomObject customObject];
object.className = @"Movie"; // your Class name
 
// Object fields
[object.fields setObject:@"Star Wars" forKey:@"name"];
[object.fields setObject:[NSNumber numberWithFloat:9.1f] forKey:@"rating"];
[object.fields setObject:[NSNumber numberWithBool:NO] forKey:@"documentary"];
[object.fields setObject:@"fantasy" forKey:@"genre"];
[object.fields setObject:@"Star Wars is an American epic space opera franchise consisting of a film series created by George Lucas." forKey:@"descriptions"];
 
[QBRequest createObject:object successBlock:^(QBResponse *response, QBCOCustomObject *object) {
     // do something when object is successfully created on a server
} errorBlock:^(QBResponse *response) {
     // error handling
     NSLog(@"Response error: %@", [response.error description]);
}];


Retrieve records

By ID

To retrieve a record by id:

[QBRequest objectWithClassName:@"Note" ID:@"51c9ab92535c12951b0032d6" successBlock:^(QBResponse *response, QBCOCustomObject *object) {
    // do something with retrieved object
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


By IDs

To retrieve records by ids:

[QBRequest objectsWithClassName:@"Note" IDs:@[@"51c9aafe535c127d98004a13",@"51c9aafe535c127d98004a14", @"51c9aafe535c127d98004a16"] successBlock:^(QBResponse *response, NSArray *objects) {
    // response processing
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


With filters

There are lots of operators and filters that you can use to retrieve records:


Filters

The request can contain all, some or none of next filters.

Filter Applicable to types Usage example Description
{field_name} All types [request setObject:@(2) forKey:@"rating"]; Search records with field which contains exactly specified value
{field_name}[{search_operator}] All types [request setObject:@(2) forKey:@"rating[gt]"]; Search record with field which contains value according to specified value and operator
sort_asc All types [request setObject:@"field_name" forKey:@"sort_asc"]; Search results will be sorted by specified field in ascending order
sort_desc All types [request setObject:@"field_name" forKey:@"sort_desc"]; Search results will be sorted by specified field in descending order
skip Integer [request setObject:@(100) forKey:@"skip"]; Skip N records in search results. Useful for pagination. Default (if not specified): 0
limit Integer [request setObject:@(100) forKey:@"limit"]; Limit search results to N records. Useful for pagination. Default value - 100. Also can set 1000.If limit is equal to -1 only last record will be returned
count Integer [request setObject:@(1) forKey:@"count"]; Count search results. Response will contain only count of records found
output[include] All types [request setObject:@"name,rating" forKey:@"output[include]"]; The output parameter takes the form of a record with a list of fields for inclusion or exclusion from the result set. output[include] specifies the fields to include. The _id field is, by default, included in the result set. To exclude the _id field from the result set, you need to specify in the output[exclude] value the exclusion of the _id field.
output[exclude] All types [request setObject:@"name,rating" forKey:@"output[exclude]"]; The output parameter takes the form of a record with a list of fields for inclusion or exclusion from the result set. output[exclude] specifies the fields to exclude. The _id field is, by default, included in the result set. To exclude the _id field from the result set, you need to specify in the output[exclude] value the exclusion of the _id field.
near Location [request setObject:@"23.4545,56.1233;10" forKey:@"user_location[near]"]; Search records in a specific radius with current position in meters. Value format: longitude,latitude;radius (in meters)


Search operators

The request can contain all, some or none of next search operators. Combinations of operators are allowed.

Operator Applicable to types Usage example Description
lt Integer, Float [request setObject:@(5) forKey:@"rating[lt]"]; Less Than operator
lte Integer, Float [request setObject:@(5) forKey:@"rating[lte]"]; Less Than or Equal to operator
gt Integer, Float [request setObject:@(5) forKey:@"rating[gt]"]; Greater Than operator
gte Integer, Float [request setObject:@(5) forKey:@"rating[gte]"]; Greater Than or Equal to operator
ne Integer, Float, String, Boolean [request setObject:@(5) forKey:@"rating[ne]"]; Not Equal to operator
in Integer, Float, String [request setObject:@"man,golf" forKey:@"tags[in]"]; Contained IN array operator
nin Integer, Float, String [request setObject:@"man,golf" forKey:@"tags[nin]"]; Not contained IN array
all Array [request setObject:@"man,golf" forKey:@"tags[all]"]; ALL contained IN array
or Integer, Float, String 1.[request setObject:@"igor,bob" forKey:@"name[or]"];
2.[request setObject:@"igor" forKey:@"name[or]"]; [request setObject:@"khomenko" forKey:@"lastname[or]"];
1.Will return records with name igor or bob
2.Will return records with name igor or lastname khomenko
ctn String [request setObject:@"ar" forKey:@"name[ctn]"]; Will return all records where username field contains ar substring


For example, if we want to retrieve 5 movies that:

  • Have a rating > 5.5
  • Are not documentaries.
  • Must be sorted by the rating field in ascending order.
NSMutableDictionary *getRequest = [NSMutableDictionary dictionary];
[getRequest setObject:@"5.5" forKey:@"rating[gt]"];
[getRequest setObject:@"5" forKey:@"limit"];
[getRequest setObject:[NSNumber numberWithBool:NO] forKey:@"documentary"];
[getRequest setObject:@"rating" forKey:@"sort_asc"];
 
[QBRequest objectsWithClassName:@"Movie" extendedRequest:getRequest successBlock:^(QBResponse *response, NSArray *objects, QBResponsePage *page) {
    // response processing
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];

Update record

To update an existing record you should know the record's ID. Let's update Movie with ID of 502f7c4036c9ae2163000002 - and set rating to 7.88:

QBCOCustomObject *object = [QBCOCustomObject customObject];
object.className = @"Movie";
[object.fields setObject:@"7.88" forKey:@"rating"];
object.ID = @"502f7c4036c9ae2163000002";
 
[QBRequest updateObject:object successBlock:^(QBResponse *response, QBCOCustomObject *object) {
    // object updated
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}


Also there are Special update operators, that are very helpful for some purpose, e.g. update Array field etc:

Special update oparators

Operator Applicable to types Usage example Description
inc Integer, Float [operators setObject:@(1) forKey:@"inc[rating]"]; Increment field to specified value. Value can positive or negative (i.e. decrement operation)
pull Arrays [operators setObject:@"man" forKey:@"pull[tags]"]; Removes specified value from array field
pull with filter Arrays [operators setObject:@(10) forKey:@"pull[user_ids][gt]"]; Removes all elements, which filtered by filter operator, from array
pull_all Arrays [operators setObject:@(10) forKey:@"pull_all[user_ids][]"];
[operators setObject:@(11) forKey:@"pull_all[user_ids][]"];
Removes all specified values from array
pop Arrays [operators setObject:@(1) forKey:@"pop[tags]"]; Removes last element from array. To remove first element value should be equal -1
push Arrays [operators setObject:@"one" forKey:@"push[tags]"];
[operators setObject:@"two" forKey:@"push[tags]"];
Appends specified values to array
add_to_set Arrays [operators setObject:@"man" forKey:@"add_to_set[tags]"]; Adds a value to an array only if the value is not in the array already
Update array element by index operator Arrays [operators setObject:@"two" forKey:@"tags[1]"]; Update array element by index


Let's update an element with index 1 in array 'tags' with value 'man':

QBCOCustomObject *object = [QBCOCustomObject customObject];
object.className = @"Movie";
object.ID = @"502f7c4036c9ae2163000002";
 
NSMutableDictionary *operators = [NSMutableDictionary dictionary];
[operators setObject:@"man" forKey:@"tags[1]"];
 
[QBRequest updateObject:object specialUpdateOperators:operators successBlock:^(QBResponse *response, QBCOCustomObject *object) {
    // object updated
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}


Delete records

To delete existing records you should know the record's ID. Let's delete a Movie with the ID 502f83ed36c9aefa62000002:

NSString *ID = @"502f83ed36c9aefa62000002";
NSString *className = @"Movie";
 
[QBRequest deleteObjectWithID:ID className:className successBlock:^(QBResponse *response) {
    // object deleted
} errorBlock:^(QBResponse *error) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


Multi operations

Is it possible to perform some operations on multiple objects in a single query.

Create multiple records

Creating multiple records in a single query:

QBCOCustomObject *object1 = [QBCOCustomObject customObject];
[object1.fields setObject:@"2049124" forKey:@"rating"];
QBCOCustomObject *object2 = [QBCOCustomObject customObject];
[object2.fields setObject:@"12" forKey:@"rating"];
 
[QBRequest createObjects:@[object1, object2] className:@"Movie" successBlock:^(QBResponse *response, NSArray *objects) {
    // response processing
} errorBlock:^(QBResponse *error) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


Update multiple records

Update multipling records in a single query:

QBCOCustomObject *object1 = [QBCOCustomObject customObject];
object1.ID = @"5228ad042195be5d8d41bd99";
[object1.fields setObject:@"101" forKey:@"rating"];
//
QBCOCustomObject *object2 = [QBCOCustomObject customObject];
object2.ID = @"5228ad042195be5d8d41bd9a";
[object2.fields setObject:@"201" forKey:@"rating"];
//
QBCOCustomObject *object3 = [QBCOCustomObject customObject];
object3.ID = @"5228ad042195be5d8d41bd9a33";
[object3.fields setObject:@"31" forKey:@"rating"];
 
[QBRequest updateObjects:@[object1, object2, object3] className:@"SuperSample" successBlock:^(QBResponse *response, NSArray *objects, NSArray *notFoundObjectsIds) {
    // response processing
} errorBlock:^(QBResponse *error) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


Delete multiple records

Deleting multiple records in a single query:

NSArray *IDs = @[@"51c9aafe535c127d98004a15", @"51c9ab92535c12951b0032d6", @"51c9ab92535c12951b0032da", @"51c9ab92535c12951b0032de", @"52283b38535c12fa32010efd"];
 
NSString *className = @"Movie";
 
[QBRequest deleteObjectsWithIDs:IDs className:className
successBlock:^(QBResponse *response, NSArray *deletedObjectsIDs, NSArray *notFoundObjectsIDs, NSArray *wrongPermissionsObjectsIDs) {
    // response processing
} errorBlock:^(QBResponse *error) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];

Relations

We can allow relations between 2 objects to be organized - just use the special field _parent_id.

For example, if you want to add Comments to a movie - you can use this code snippet below:

QBCOCustomObject *object = [QBCOCustomObject customObject];
object.className = @"Comment"; // your Class name
 
// Object fields
[object.fields setObject:@"The first film in the series was originally released on May 25, 1977, under the title Star Wars, by 20th Century Fox" forKey:@"text"];
[object.fields setObject:@"50aa4d8fefa357fa14000001" forKey:@"_parent_id"]; // Movie ID
 
[QBRequest createObject:object successBlock:^(QBResponse *response, QBCOCustomObject *object) {
    // do something when object is successfully created on a server
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


This is a strong reference - it means that if you delete parent record (Movie) - all the child records (Comments) will be deleted too. This field (_parent_id) may be included in Retrieve/Create/Update queries as well.

Permissions

A Permission (access control list) is a list of permissions attached to a record in the Custom Objects module. This list specifies which users are granted access to records, as well as what operations are allowed on given objects (READ,CREATE,UPDATE,DELETE).

Each entry in a typical Permissions specifies a subject and an operation. For instance, if a record has a permission that contains (Garry, EDIT), this would give Garry permission to edit this record.

Read Permissions REST API description to better understand how it works

There are 4 typical operations on record:

  • CREATE
  • READ
  • UPDATE
  • DELETE

CREATE operations can't be set through API (only in Admin panel)

Each operation has information on who can perform it on object.

There are 5 values (enum QBCOPermissionsAccess):

  • QBCOPermissionsAccessOpen - any user can perform operation on this record
  • QBCOPermissionsAccessOwner - only owner can perform operation on this record
  • QBCOPermissionsAccessNotAllowed - nobody can perform operation on this record (except Owner)
  • QBCOPermissionsAccessOpenForUsersIDs - users with these IDs can perform operation on this record
  • QBCOPermissionsAccessOpenForGroups - users in these groups can perform operation on this record

Note: Owners always have access to their own records (except for any case where Class permissions level is enabled)


Creating records with Permissions

Let's create a record with the following permissions:

  • READ: Open
  • UPDATE: Users in groups golf, man
  • DELETE: Users with IDs 3060, 63635
QBCOCustomObject *object = [QBCOCustomObject customObject];
object.className = @"Movie"; // your Class name
 
// Object fields
[object.fields setObject:@"Star Wars" forKey:@"name"];
[object.fields setObject:@"fantasy" forKey:@"genre"];
 
// permissions
QBCOPermissions *permissions = [QBCOPermissions permissions];
// READ
//
permissions.readAccess = QBCOPermissionsAccessOpen;
// UPDATE
//
permissions.updateAccess = QBCOPermissionsAccessOpenForGroups;
permissions.usersGroupsForUpdateAccess = @[@"golf", @"man"];
// DELETE
//
permissions.deleteAccess = QBCOPermissionsAccessOpenForUsersIDs;
permissions.usersIDsForDeleteAccess = @[@3060, @63635];
 
object.permissions = permissions;
 
[QBRequest createObject:object successBlock:^(QBResponse *response, QBCOCustomObject *object) {
    // do something when object is successfully created on a server
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


Obtaining a record's Permissions

You can obtain info about record permissions by looking at it's ID - Individual users are restricted to information on their own records:

[QBCustomObjects permissionsForObjectWithClassName:@"SuperSample" ID:@"51c9aafe535c127d98004a13" successBlock:^(QBResponse *response, QBCOPermissions *permissions) {
    // response processing
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];


Updating a record's Permissions

Let's update a record's permissions to the following:

  • READ: Users in groups car, developers
  • UPDATE: Owner
  • DELETE: Owner
QBCOCustomObject *object = [QBCOCustomObject customObject];
object.className = @"Movie"; // your Class name
 
// permissions
QBCOPermissions *permissions = [QBCOPermissions permissions];
// READ
//
permissions.readAccess = QBCOPermissionsAccessOpenForGroups;
permissions.usersGroupsForUpdateAccess = @[@"car", @"developers"];
// UPDATE
//
permissions.updateAccess = QBCOPermissionsAccessOwner;
// DELETE
//
permissions.deleteAccess = QBCOPermissionsAccessOwner;
 
object.permissions = permissions;
 
[QBRequest updateObject:object specialUpdateOperators:nil successBlock:^(QBResponse *response, QBCOCustomObject *object) {
    // object updated
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];

Files

Custom Objects module supports the ‘File’ field type. It is created to easily work with content from Custom Objects module. There is an ability to upload, download, update and delete content of file fields.

The max file size is 32 MB.

Uploading/Updating a file

QBCOFile *file = [QBCOFile file];
file.name = @"plus";
file.contentType = @"image/png";
file.data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"plus" ofType:@"png"]];
 
[QBRequest uploadFile:file className:@"Movie" objectID:@"5256c265535c128020000182" fileFieldName:@"image" successBlock:^(QBResponse *response) {
    // uploaded
} statusBlock:^(QBRequest *request, QBRequestStatus *status) {
    // handle progress            
} errorBlock:^(QBResponse *response) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];

Downloading a file

[QBRequest downloadFileFromClassName:@"Movie" objectID:@"5256c265535c128020000182" fileFieldName:@"image"
successBlock:^(QBResponse *response, NSData *loadedData) {
    // file downloaded
} statusBlock:^(QBRequest *request, QBRequestStatus *status) {
    // handle progress            
} errorBlock:^(QBResponse *error) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];

Deleting a file

[QBRequest deleteFileFromClassName:@"Movie" objectID:@"5256c265535c128020000182" fileFieldName:@"image" successBlock:^(QBResponse *response) {
    // file deleted
} errorBlock:^(QBResponse *error) {
    // error handling
    NSLog(@"Response error: %@", [response.error description]);
}];