Code Samples

Cortex Code samples

Login

[[Medable client]
 loginWithEmail:@"your email here"
 password:@"your password here"
 verificationToken:nil
 singleUse:NO
 callback:^(MDAccount * _Nullable localUser, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
 }];
Medable.client().login(withEmail: "your email here",
                       password: "your password here",
                       verificationToken: nil,
                       singleUse: false)
{
    (account: MDAccount?, fault: MDFault?) in
    
    if let loginFault = fault {
        // handle fault
    }
}

Logout

[[Medable client] logout:^(MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
 }];
Medable.client().logout {
    (fault: MDFault?) in
    if let logoutFault = fault {
        // handle fault
    }
}

Register User

[[Medable client]
 registerAccountWithFirstName:@"Charles"
 lastName:@"Best"
 email:@"[email protected]"
 mobile:@"1-650-555-5555"
 password:@"Thanks for the break, Banting!"
 gender:@"m"
 dob:[MDDateUtilities dateFromString:@"1899-02-27"]
 role:nil
 profileInfo:nil
 thumbImage:nil
 timeZone:nil
 customPropValues:nil
 callback:^(MDAccount* account, MDFault *fault)
 {
     if ( fault != nil)
     {
         // Handle the error (e.g. show alert with fault.message)
     }
     else
     {
         // Check whether activation is required before authentication
         BOOL requiresActivation = [account activationRequired] ? [[account activationRequired] boolValue] : NO;
         
         // Handle the case when requiresActivation == YES here
     }
 }];
Medable.client().registerAccount(
    withFirstName: "Charles",
    lastName: "Best",
    email: "[email protected]",
    mobile: "1-650-555-5555",
    password: "Thanks for the break, Banting!",
    gender: "m",
    dob: MDDateUtilities.date(from: "1899-02-27"),
    role: nil,
    profileInfo: nil,
    thumbImage: nil,
    timeZone: nil,
    customPropValues: nil) {
        (account: MDAccount?, fault: MDFault?) in
        
        if let registrationFault = fault {
            // handle fault
        }
}

Create Object

Let's suppose we are using a custom Prescription object definition that was created using the Data Model Setup guide.

Now, we want to create instances of those objects using Cortex from the client side.

NSDictionary *prescriptionBody = @{
                                   @"c_date": [NSDate new],
                                   @"c_dispense": @3,
                                   @"c_patient": @"some patient Id reference",
                                   @"c_provider": @"some provider Id reference",
                                   @"c_refills": @2,
                                   @"c_rx": @"Prescription details"
                                   };

[[Medable client]
 createObjectWithContext:@"c_prescription"
 body:prescriptionBody
 callback:^(MDObjectInstance * _Nullable instance, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
     else if (instance)
     {
         // newly created instance
     }
 }];
let prescriptionBody: [ String: Any ] = [
    "c_date": Date(),
    "c_dispense": 3,
    "c_patient": "some patient Id reference",
    "c_provider": "some provider Id reference",
    "c_refills": 2,
    "c_rx": "Prescription details"
]

Medable.client().createObject(
    withContext: "c_prescription",
    body: prescriptionBody) {
        (instance: MDObjectInstance?, fault: MDFault?) in
        
        if let createInstanceFault = fault {
            // handle fault
        } else if let instance = instance {
            // newly created instance
        }
}

Edit Object

Let's suppose we are using a custom Prescription object definition that was created using the Data Model Setup guide.

Now, we want to edit an existing instance of that type of object using Cortex from the client side.

NSDictionary *propertiesToUpdate = @{
                                     @"c_dispense": @7,
                                     @"c_refills": @9,
                                     @"c_rx": @"Updated prescription details"
                                     };

[[Medable client]
 updateObjectWithContext:@"c_prescription"
 objectId:[MDObjectId objectIdWithString:@"the object's Id"]
 body:propertiesToUpdate
 callback:^(MDObjectInstance * _Nullable instance, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
     else if (instance)
     {
         // edited instance
     }
 }];
let propertiesToUpdate: [ String: Any ] = [
    "c_dispense": 7,
    "c_refills": 9,
    "c_rx": "Updated prescription details"
]

Medable.client().updateObject(
    withContext: "c_prescription",
    objectId: MDObjectId(string: "the object's Id")!,
    body: propertiesToUpdate) {
        (instance: MDObjectInstance?, fault: MDFault?) in
        
        if let createInstanceFault = fault {
            // handle fault
        } else if let editedInstance = instance {
            // edited instance
        }
}

List Objects

Let's suppose we are using a custom Prescription object definition that was created using the Data Model Setup guide.

Now, we want to list existing instances of that type of object using Cortex from the client side.

📘

Note

For paginated listing take a look the Pagination Helpers guide.

[[Medable client]
 listObjectsWithContext:@"c_prescription"
 parameters:nil
 callback:^(NSArray<MDObjectInstance *> * _Nullable objects, NSNumber * _Nullable hasMore, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
     else
     {
         // hasMore is true if there are more objects to load --there's a limit in the amount of returned objects.
         // objects contains the returned object instances
     }
 }];
Medable.client().listObjects(
    withContext: "c_prescription",
    parameters: nil) {
        (objects: [MDObjectInstance]?, hasMore: NSNumber?, fault: MDFault?) in
        
        if let listFault = fault {
            // handle fault
        } else if let objects = objects, let hasMore = hasMore {
            // hasMore is true if there are more objects to load --there's a limit in the amount of returned objects.
            // objects contains the returned object instances
        }
}
📘

Note

If you need to use a custom class instead of MDObjectInstance and want Cortex to return instances of your class instead, follow the Cortex Objects guide.

Delete Object

[[Medable client]
 deleteObjectWithContext:@"c_prescription"
 objectId:[MDObjectId objectIdWithString:@"the object's Id"]
 reason:nil
 callback:^(MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
 }];
Medable.client().deleteObject(
    withContext: "c_prescription",
    objectId: MDObjectId(string: "the object's Id")!,
    reason: nil) {
        (fault: MDFault?) in
        
        if let deleteFault = fault {
            // handle fault
        }
}

File Download

Files can be downloaded using one of two methods.

Using a download path:

NSString *filePath = [MDAPIClient routeWithComponents:@[ @"path", @"to", @"file" ]];

[MDAPIClient
 downloadFileAtPath:filePath
 callback:^(id  _Nullable streamData, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
     else if ([streamData isKindOfClass:[UIImage class]])
     {
         // downloaded file is an instance of UIImage
     }
     else if ([streamData isKindOfClass:[NSData class]])
     {
         // downloaded file is an instance of NSData
     }
 }];
let filePath = MDAPIClient.route(withComponents: [ "path", "to", "file" ])

MDAPIClient.downloadFile(atPath: filePath) {
    (data: Any?, fault: MDFault?) in
    
    if let downloadFault = fault {
        // handle fault
    } else if let data = data as? UIImage {
        // downloaded file is an instance of UIImage
    } else if let data = data as? Data {
        // downloaded file is an instance of NSData
    }
}

Or using a MDFacet of the File.

MDFacet *aFileFacet = ...;

[aFileFacet fileDataWithCallback:^(NSData * _Nullable data, MDDataSource source, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
     else if ([data isKindOfClass:[UIImage class]])
     {
         // downloaded file is an instance of UIImage
     }
     else if ([data isKindOfClass:[NSData class]])
     {
         // downloaded file is an instance of NSData
         
         // Use source to query the source of the data
         switch (source)
         {
             case MDDataSourceCache:
                 // data comes from local cache
                 break;
             case MDDataSourceRemote:
                 // data was just downloaded
                 break;
             default:
                 //
                 break;
         }
     }
 }];
let aFileFacet: MDFacet! = ...

aFileFacet.fileData {
    (data: Data?, source: MDDataSource, fault: MDFault?) in
    
    if let fault = fault {
        // handle fault
    }
    else if let data = data as? UIImage {
        // downloaded file is an instance of UIImage
    } else if let data = data as? Data {
        // downloaded file is an instance of NSData
        
        // Use source to query the source of the data
        switch source {
        case MDDataSourceCache:
            // data comes from local cache
            break
        case MDDataSourceRemote:
            // data was just downloaded
            break
        default:
            //
            break
        }
    }
}

File Upload

File uploads are a two step process as described in the File Uploads documentation.

  1. In the first step, a file property name and the file name is sent to the server. This could happen when creating an object and also when editing an object.

  2. In the response of the first step, that is, in the callback of whichever method was used in step 1 --create or update; is when the actual file upload takes place using upload information sent by the Cortex API.

For this sample, let's suppose we are creating an instance of a c_anObject object type that, has a c_image File property. We want to upload an image to the content facet of that File.

// STEP 1 - Create/Update the object and send a file property key/value pairs
UIImage *fileToUpload = ...;
// Note: fileToUpload can be an instance of NSData too.

// File values are always key = facet name, value = file name.
NSDictionary *filePropValue = @{ @"content": fileToUpload };

// --- Optinally the mime type can be set:
NSDictionary *filePropValue = @{ @"content": @{ @"mime": @"image/png", @"data": fileToUpload }};
// ---

// Create/Update bodies are always key = prop name, value = prop value or the right type.
NSDictionary *createBody = @{
                             @"c_aPropName": @"aPropValue",
                             @"c_image": filePropValue,
                             @"c_someOtherPropName": @55
                             };

[[Medable client]
 createObjectWithContext:@"c_anObject"
 body:createBody
 callback:^(MDObjectInstance * _Nullable instance, MDFault * _Nullable fault)
 {
     if (fault)
     {
         // handle fault
     }
     else if (instance)
     {
         // STEP 2 - File Upload - Performed internally by Cortex. Read "Managing File Uploads" to know how to keep track of file uploads. Files are also cached and encrypted locally by Cortex.
     }
 }];
// STEP 1 - Create/Update the object and send a file property key/value pairs
let fileToUpload: UIImage! = ...
// Note: fileToUpload can be an instance of NSData too.

// File values are always key = facet name, value = file name.
let filePropValue = [ "content": fileToUpload ]

// --- Optinally the mime type can be set:
let filePropValue = [ "content": [ "mime": "image/png", "data": fileToUpload ] ]
// ---

// Create/Update bodies are always key = prop name, value = prop value or the right type.
let createBody: [ String: Any ] = [
    "c_aPropName": "aPropValue",
    "c_image": filePropValue,
    "c_someOtherPropName": 55
]

Medable.client().createObject(
    withContext: "c_anObject",
    body: createBody) {
        (instance: MDObjectInstance?, fault: MDFault?) in
        
        if let fault = fault {
            // handle fault
        } else if let instance = instance {
            // STEP 2 - File Upload - Performed internally by Cortex. Read "Managing File Uploads" to know how to keep track of file uploads. Files are also cached and encrypted locally by Cortex.
        }
}
📘

File Uploads

For a deeper management of file uploads take a look at the Managing File Uploads documentation.