Swift 2.2

Here, we will explain how to use the functionalities the CloudRail SI iOS SDK provides.

We assume you have already installed the library, if not, have a look at Installation.

The code samples that come with each function description assume that a service that implements the respective interface has already been instantiated.

If you want to run the code samples refer to Services to find instructions on how to instantiate your service and then come back here.

General

In order to understand what functionality which service offers we need to understand the concept of interfaces and implementing services.

CloudRail SI's services all implement one or multiple of the following interfaces:

Name What is does Implementing services
Cloud Storage Upload, download, copy, delete, move, create and get information about files and/or folders in a CloudStorage provider Dropbox, Google Drive, OneDrive, OneDrive Business, Box,Egnyte
Business Cloud Storage Upload and download files, create and delete buckets, list buckets and files, get information about files Amazon S3, Microsoft Azure, Backblaze, Rackspace
Social Profile Retrieve information about a user, including an identifier to realize "Login with ..." Facebook, GitHub, Google+, LinkedIn, Slack, Twitter, Windows Live, Yahoo, Instagram
Social Interaction Retrieve a list of connections/friends/etc and post an update Facebook, Twitter
Payment Manage charges, refunds and subscriptions of clients who make payments with their credit card to an account on the respective service PayPal, Stripe
Email Programmatically send text/HTML emails to one or many addresses Mailjet, SendGrid
SMS Programmatically send SMS to phones Twilio, Nexmo
Points of Interest Get a list of points of interest in around a given location in a certain radius filtered by search terms and/or categories Google Places, Foursquare, Yelp

Each interface comes with a set of functionalities and implementing that interface implies that the respective service supports all the functionality from that interface.

Interfaces

Cloud Storage

Introduction

The CloudStorage interface bundles functionality around interaction with cloud storage providers. Its main challenge consists in abstracting about how files and folders are referenced. For the sake of easy usage, we have chosen paths over identifiers. This means every file and folder will be referenced by its full path starting at the root folder for all the functions in this interface.

For example, /TestFolder/UserData.csv refers to a file called UserData.csv residing in the TestFolder folder which in turn is located at root.

Implementing services

Function Overview

Did not find the function you need? Try Advanced Request!

Functions

Upload

Declaration
/**
 Uploads a file to a cloud storage
 - parameter filePath:  filePath The path where to store the file from the root folder and including the name, e.g /myFolder/myFile.jpg
 - parameter stream:    A stream from which the file can bwe read
 - parameter size:      The size in bytes of the data that can be read from the stream
 - parameter overwrite: Boolean value determining if an existing file should be overwriten
 - throws: CloudRailError
 */
 func uploadFileToPath(filePath: String, stream: NSInputStream, size: CLong, overwrite: Bool) throws ->Void
Example
// Loads a file from the application's bundle and uploads it (change the file's name in the process)
do{
  let cloudStorage : CloudStorageProtocol = Dropbox.init(clientId: "", clientSecret: "")
  //Make sure to properly unwrap the optional
  let filepath = NSBundle.mainBundle().pathForResource("UserData", ofType: "csv")!
  let data = NSData.init(contentsOfFile: filepath)!
  let inputStream = NSInputStream.init(fileAtPath: filepath)!
  try cloudStorage.uploadFileToPath("/TestFolder/Data.csv", stream: inputStream, size: data.length, overwrite: true)

} catch let error{
  print("An error: \(error)")
}

Download

Declaration
 /**
 Downloads a file from a cloud storage

 - parameter filePath: filePath The path to the file from the root folder and including the name, e.g /myFolder/myFile.jpg

 - throws: CloudRailError

 - returns: A stream from which the file can be read
*/
public func downloadFileWithPath(filePath: String) throws -> NSInputStream
Example
do{
  let cloudStorage : CloudStorageProtocol = Dropbox.init(clientId: "", clientSecret: "")
  let inputStream = try cloudStorage.downloadFileWithPath("/TestFolder/Data.csv")
} catch let error{
  print("An error: \(error)")
}

Create Folder

Declaration
/**
 Creates a folder at the given path

 - parameter folderPath: folderPath The path to the folder from the root folder and including the name, e.g. /myNewFolder

 - throws: CloudRailError
 */
public func createFolderWithPath(folderPath: String) throws
Example
do{
  try cloudStorage.createFolderWithPath("/TestFolder")
} catch let error{
  print("An error: \(error)")
}

Copy

Declaration
/**
     Copies a file from one path in the cloud storage to another

 - parameter sourcePath:      sourcePath The path of the origin file from the root folder and including the name
 - parameter destinationPath: destinationPath The path of the destination file from the root folder and including the name

 - throws: CloudRailError

*/
public func copyFileFromPath(sourcePath: String, destinationPath: String) throws
Example
do{
  try cloudStorage.copyFileFromPath("/TestFolder/Data.csv", destinationPath: "/CopyFolder/Data.csv")
} catch let error{
  print("An error: \(error)")
}

Delete

Declaration
/**
 Deletes a file from the cloud storage

 - parameter filePath: filePath The path to the file to be deleted from the root folder and including the name

 - throws: CloudRailError
 */
public func deleteFileWithPath(filePath: String) throws
Example
do{
  try cloudStorage.deleteFileWithPath("/TestFolder/UserData.csv")
} catch let error{
  print("An error: \(error)")
}

Move

Declaration
/**
 Moves a file in the cloud storage

 - parameter sourcePath:      sourcePath The path to the file which should be moved from the root folder and including the name
 - parameter destinationPath: destinationPath The path to move the file to from the root folder and including the name

 - throws: CloudRailError

 */
public func moveFileFromPath(sourcePath: String, destinationPath: String) throws
Example
do{
  try cloudStorage.moveFileFromPath("TestFolder/file.jpg", destinationPath: "AnotherFolder/subfolder/")
} catch let error{
  print("An error: \(error)")
}

Get Metadata

Declaration
/**
     Gets metadata about the file/folder

 - parameter filePath: filePath The path to the file from the root folder and including the name

 - throws: CloudRailError

 - returns: CRCloudMetadata object, a container for metadata
 */
public func metadataOfFileWithPath(filePath: String) throws -> CRCloudMetaData
Example
do{
  try cloudStorage.metadataOfFileWithPath("TestFolder/file.jpg")
} catch let error{
  print("An error: \(error)")
}

Get Children

Declaration
/**
 Gets the metadata of this folder's children

 - parameter folderPath: folderPath The path to the file from the root folder and including the name

 - throws: CloudRailError

 - returns: A container for metadata CRCloudMetaData Objects
 */
public func childrenOfFolderWithPath(folderPath: String) throws -> NSMutableArray
Example
do{
  try cloudStorage.childrenOfFolderWithPath("TestingFolder/subfolder/")
} catch let error{
  print("An error: \(error)")
}

Get Children Page

Declaration
/**
 Gets the metadata of this folder's children but can be limited

 - parameter folderPath: folderPath The path to the file from the root folder and including the name

 - parameter offset: offset The offset for the children

 - parameter limit: limit The amount of children returned

 - throws: CloudRailError

 - returns: A container for metadata CRCloudMetaData Objects
 */
public func childrenOfFolderWithPath(folderPath: String, offset: CLong, limit: CLong) throws -> NSMutableArray
Example
do{
  try cloudStorage.childrenOfFolderWithPath("TestingFolder/subfolder/", 0, 10)
} catch let error{
  print("An error: \(error)")
}

Get User's Login Identifier

Declaration
/**
 * @return The currently logged in user's login identifier (name/email/...).
 */
-(NSString *) userLogin;
Example
NSString * userLogin = [cloudStorage userLogin];

Get User's Name

Declaration
/**
 Method to retrieve a user's name

 - throws: CloudRailError

 - returns: String, the user name.
 */
public func userName() throws -> String
Example
do{
  try cloudStorage.userName()
} catch let error{
  print("An error: \(error)")
}

Explicit Login

Declaration
/**
     * (Optional) Explicitly triggers user authentication.
 * Allows better control over the authentication process.
 * Optional because all methods that require prior authentication will trigger it automatically,
 * unless this method has been called before.
 */
public func login() throws
Example
do{
  try cloudStorage.login()
} catch let error{
  print("An error: \(error)")
}

Explicit Logout

Declaration
/**
 * (Optional) Revokes the current authentication.
 */
public func logout() throws
Example

do{
  try cloudStorage.logout()
} catch let error{
  print("An error: \(error)")
}

Save As String

Declaration
/**
 A method to retrieve the data from a service that is intended for persistent storage

 - throws: CloudRailError

 - returns: String, The data of the service that should be stored persistently, e.g. access credentials
 */
public func saveAsString() throws -> String
Example
do{
  let string = try cloudStorage.saveAsString()
} catch let error{
  print("An error: \(error)")
}

Load As String

Declaration
/**
 Loads/restores data saved by saveAsString method into the service

 - throws: CloudRailError

 */
public func loadAsString(savedState: String) throws
Example
do{
  let string = try cloudStorage.loadAsString()
} catch let error{
  print("An error: \(error)")
}

Business Cloud Storage

Introduction

This is a common interface for Bucket based Cloud Storage Services. Instead of organizing files in nested folders, they reside in a bucket.

Implementing services

Function Overview

Functions

List Buckets

Declaration
/**
 * Get a list of all buckets within your account.
 *
 * @return List of buckets. This might be an empty list if there are no buckets.
 */
 func listBuckets() throws ->NSMutableArray

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end
Example
do{
  try cloudStorage.listBuckets()
} catch let error{
  print("An error: \(error)")
}

Create Bucket

Declaration
/**
 * Creates a new empty bucket.
 *
 * @param name The name of the new bucket.
 * @return The newly created bucket.
 */
func createBucket(_ bucketName: String) throws ->CRBucket

 @interface CRBucket : CRSandboxObject
   @property (nonatomic) NSString * identifier;
   @property (nonatomic) NSString * name;
 @end
Example
do{
  try cloudStorage.createBucket("[bucket_name]")
} catch let error{
  print("An error: \(error)")
}

Delete Bucket

Declaration
/**
 * Deletes the specified bucket with all its content.
 *
 * @param bucket The bucket which will be deleted.
 */
 func deleteBucketWithID(_ bucket: CRBucket) throws ->Void

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end
Example
do{
  try cloudStorage.deleteBucket(bucket)
} catch let error{
  print("An error: \(error)")
}

List Files

Declaration
/**
 * Get a list of files contained in the specified bucket.
 *
 * @param bucket The bucket containing the files.
 */
 func listFilesInBucket(_ bucket: CRBucket) throws ->NSMutableArray

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end

@interface CRBusinessFileMetaData : CRSandboxObject

  @property (nonatomic) NSString * fileID;
  @property (nonatomic) NSString * fileName;

  @property (nonatomic) NSNumber * size;
  @property (nonatomic) NSNumber * lastModified;

@end
Example
do{
  try cloudStorage.listFilesInBucket(bucket)
} catch let error{
  print("An error: \(error)")
}

Upload File

Declaration
/**
 * Uploads a new file into a bucket or replaces the file if it is already present.
 *
 * @param bucket  The bucket into which the file shall be put.
 * @param name    The name of the file.
 * @param stream The file content as a readable stream.
 * @param size    The amount of bytes that the file contains.
 */
func uploadFileToBucket(_ bucket: CRBucket, name: String, stream: InputStream, size: CLong) throws ->Void

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end
Example
let bucket : CRBucket = CRBucket.init()
bucket.name = "[bucketName]";
bucket.identifier = "[identifier]"

let path = Bundle.main.path(forResource: "UserData", ofType: "csv")!
let fileAttributes = try! FileManager.default.attributesOfItem(atPath: path)
let fileSize: UInt64 = fileAttributes[FileAttributeKey.size] as! UInt64
let stream = InputStream.init(fileAtPath: path)!


do{
  try cloudStorage.uploadFileToBucket(bucket, name: "[fileName]", stream: stream, size:fileSize)
} catch let error{
  print("An error: \(error)")
}

Delete File

Declaration
/**
 * Deletes a file within a bucket.
 *
 * @param fileName The name of the file.
 * @param bucket   The bucket that contains the file.
 */
 func deleteFileWithName(_ fileName: String, bucket: CRBucket) throws ->Void

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end
Example
do{
  try cloudStorage.deleteFileWithName("[filename]", bucket: bucket)
} catch let error{
  print("An error: \(error)")
}

Download File

Declaration
//**
 * Downloads a file from a bucket.
 *
 * @param bucket   The bucket which contains the file.
 * @param fileName The name of the file.
 * @return The content of the file as a readable stream.
 */
 func downloadFileWithName(_ fileName: String, bucket: CRBucket) throws ->InputStream

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end
Example
do{
  stream = try cloudStorage.downloadFileWithName("[filename]", bucket: bucket)
} catch let error{
  print("An error: \(error)")
}
//READ FROM STREAM

Get File Metadata

Declaration
/**
 * Get metadata of a file containing the name, the size and the last
 * modified date.
 *
 * @param bucket   The bucket where the file is located.
 * @param fileName The name of the file.
 */
 func metadataOfFileWithPath(_ bucket: CRBucket, fileName: String) throws ->CRBusinessFileMetaData

@interface CRBucket : CRSandboxObject
  @property (nonatomic) NSString * identifier;
  @property (nonatomic) NSString * name;
@end

@interface CRBusinessFileMetaData : CRSandboxObject

  @property (nonatomic) NSString * fileID;
  @property (nonatomic) NSString * fileName;

  @property (nonatomic) NSNumber * size;
  @property (nonatomic) NSNumber * lastModified;

@end
Example
do{
  metadata = try cloudStorage.metadataOfFileInBucket(bucket, fileName: "[filename]")
} catch let error{
  print("An error: \(error)")
}

Social Profile

Introduction

The Profile interface is a common interface for Services that provide unique user identifiers and general user information.

With the getIdentifier function, "Login with ..." scenarios can be easily implemented: Whenever a user needs to login/signup, call the getIdentifier function of an instance of this interface. This will have the user login and then return a unique identifier for this user with this service. Use this to identify a user's account with your application.

All the other information might be present or not, depending on the service and how much information the user has filled out with the respective service. To avoid unnecessary requests, information is cached up to one minute.

Implementing services

Function Overview

Did not find the function you need? Try Advanced Request!

Functions

Get Identifier

Declaration
/**

 - throws: CloudRailError

 - returns: A unique identifier for the authenticated user. All services provide this value. Useful for "Login with ...". Prefixed with the lowercased service name and a minus.
 */
public func identifier() throws -> String
Example
do{
  let identifier = try profile.identifier()
} catch let error{
  print("An error: \(error)")
}

Get Full Name

Declaration
/**

 - throws: CloudRailError

 - returns: The user's full name or null if not present
 */
public func fullName() throws -> String
Example
do{
  let fullName = try profile.fullName()
} catch let error{
  print("An error: \(error)")
}

Get Email

Declaration
/**

 - throws: CloudRailError

 - returns: The user's email address or null if not present
 */
public func email() throws -> String
Example
do{
  let email = try profile.email()
} catch let error{
  print("An error: \(error)")
}

Get Gender

Declaration
/**

 - throws: CloudRailError

 - returns: The user's gender, normalized to be one of "female", "male", "other" or null if not present
 */
public func gender() throws -> String
Example
do{
  let gender = try profile.gender()
} catch let error{
  print("An error: \(error)")
}

Get Description

Declaration
/**

 - throws: CloudRailError

 - returns: The description the user has given themselves or null if not present

 */
public func profileDescription() throws -> String
Example
do{
  let profileDescription = try profile.profileDescription()
} catch let error{
  print("An error: \(error)")
}

Get Date Of Birth

Declaration
  /**

   - throws: CloudRailError

   - returns: The date of birth in a special format, see {@link com.cloudrail.si.types.DateOfBirth DateOfBirth}
   */
  public func dateOfBirth() throws -> CRDateOfBirth
public class CRDateOfBirth : CRSandboxObject {

    public var year: NSNumber!
    public var month: NSNumber!
    public var day: NSNumber!

    /**
     *  Generated a NSDate from the properties: year, month, day
     *
     * @return NSDate the date object
     */
    public func date() -> NSDate!
}
Example
do{
  let fullName: CRDateOfBirth = try profile.dateOfBirth()
} catch let error{
  print("An error: \(error)")
}

Get Locale

Declaration
/**

 - throws: CloudRailError

 - returns: The locale/language setting of the user, e.g. "en", "de" or null if not present
 */
public func locale() throws -> String
Example
do{
  let locale = try profile.locale()
} catch let error{
  print("An error: \(error)")
}

Get Picture URL

Declaration
/**
 - throws: CloudRailError

 - returns: The URL of the user's profile picture or null if not present
 */
public func pictureURL() throws -> String
Example
do{
  let pictureURL = try profile.pictureURL()
} catch let error{
  print("An error: \(error)")
}

Explicit Login

Declaration
/**
     * (Optional) Explicitly triggers user authentication.
 * Allows better control over the authentication process.
 * Optional because all methods that require prior authentication will trigger it automatically,
 * unless this method has been called before.
 */
public func login() throws
Example

do{
  try profile.login()
} catch let error{
  print("An error: \(error)")
}

Explicit Logout

Declaration

/**
 * (Optional) Revokes the current authentication.
 */
public func logout() throws
Example
do{
  try profile.logout()
} catch let error{
  print("An error: \(error)")
}

Save As String

Declaration
/**
 A method to retrieve the data from a service that is intended for persistent storage

 - throws: CloudRailError

 - returns: String, The data of the service that should be stored persistently, e.g. access credentials
 */
public func saveAsString() throws -> String
Example

do{
  let string = try profile.saveAsString()
} catch let error{
  print("An error: \(error)")
}

Load As String

/**
 Loads/restores data saved by saveAsString method into the service

 - throws: CloudRailError

 */
public func loadAsString(savedState: String) throws
Example
do{
  let string = try profile.loadAsString()
} catch let error{
  print("An error: \(error)")
}

Social Interaction

Introduction

This is a common interface for services that provide a set of social functionalities. Currently the functionalities are limited to receiving a list of user ids with which the currently logged in user has a connection to and who is also using your app and to post an update to a users timeline.

Implementing services

Function Overview

Functions

Get Connections

Declaration
/**
 Retrieves a list of connection/friend/etc. IDs. The IDs are compatible with those returned by Profile.identifier().

 - throws: CloudRAilError

 - returns: NSMutableArray list with connections IDs.
 */
public func connections() throws -> NSMutableArray
Example
do{
  var connections = try social.connections()
} catch let error{
  print("An error: \(error)")
}

Post Update

Declaration
/**
 Creates a new post/update to the currently logged in user's wall/stream/etc.

 - parameter content: content The post's content

 - throws: CloudRailError

 */
public func postUpdateWithContent(content: String) throws
Example
do{
  try social.postUpdateWithContent("CloudRail is awesome!!!")
} catch let error{
  print("An error: \(error)")
}

Explicit Login

Declaration
/**
 * (Optional) Explicitly triggers user authentication.
 * Allows better control over the authentication process.
 * Optional because all methods that require prior authentication will trigger it automatically,
 * unless this method has been called before.
 */
public func login() throws
Example

do{
  try social.login()
} catch let error{
  print("An error: \(error)")
}

Explicit Logout

Declaration
/**
 * (Optional) Revokes the current authentication.
 */
public func logout() throws
Example
do{
  try social.logout()
} catch let error{
  print("An error: \(error)")
}

Save As String

Declaration
/**
 A method to retrieve the data from a service that is intended for persistent storage

 - throws: CloudRailError

 - returns: String, The data of the service that should be stored persistently, e.g. access credentials
 */
public func saveAsString() throws -> String
Example

do{
  let string = try social.saveAsString()
} catch let error{
  print("An error: \(error)")
}

Load As String

/**
 Loads/restores data saved by saveAsString method into the service

 - throws: CloudRailError

 */
public func loadAsString(savedState: String) throws
Example
do{
  let string = try social.loadAsString()
} catch let error{
  print("An error: \(error)")
}

Payment

Introduction

Payment is a common interface for services that allow you to collect payments from credit cards. It serves three main purposes: perform single charges, refund previously made charges and manage subscriptions. In order to properly test your integration, all services do provide some sort of testing environment and/or test values.

Implementing services

Function Overview

Functions

Create Charge

Declaration
 /**
 Charges a credit card and returns a charge resource.

 - parameter amount:   amount A positive integer in the smallest currency unit (e.g. cents)
 *      representing how much to charge the credit card.
 - parameter currency: currency A three-letter ISO code for currency.
 - parameter source:   source The credit card to be charged.

 - throws: CloudRailError

 - returns: A charge resource representing the newly created payment.
 */
public func createChargeWithAmount(amount: Int, currency: String, source: CRCreditCard) throws -> CRCharge

public class CRCharge : CRSandboxObject {

    public var identifier: String!// ID of the newly generated charge
    public var amount: NSNumber!// amount that was charged
    public var currency: String!// currency in which the amount was charged
    public var source: CRCreditCard!// credit card that was charged
    public var created: NSNumber!// current state of the charge. Possible values are: 'pending',    
    public var status: String!// current state of the charge. Possible values are: 'pending', 'succeeded' or 'failed'
    public var refunded: NSNumber!// if the payment has been completely refunded or not
}

public class CRCreditCard : CRSandboxObject {

    //CostumerData
    public var firstName: String!
    public var lastName: String!
    public var address: CRAddress!
    public var number: String!

    // Card validation code
    public var cvc: String!

    // Values between 1 and 12
    public var expire_month: NSNumber!

    // Four digit expiration data
    public var expire_year: NSNumber!

    // Can have the following values: visa, mastercard, discover, amex
    public var type: String!
}

public class CRAddress : CRSandboxObject {

    public var country: String! // ID of the newly generated charge
    public var city: String! // City/Suburb/Town/Village
    public var state: String!
    public var line1: String!// Street address/PO Box/Company name
    public var line2: String!// Apartment/Suite/Unit/Building
    public var postalCode: String!
}
Example
do{
  let creditCard = CRCreditCard.initWithCvc("", expireMonth:6, expireYear: 2021, number: "xxxxxxxxxxxxxxxx", type:"visa", firstName: "firstName", lastName:"lastName", address: address)
  let charge = try payment.createChargeWithAmount(500, currency: "USD", source: creditCard)
} catch let error{
  print("An error: \(error)")
}

Get Charge

Declaration
/**
 Returns information about an existing charge. Mostly used to get an update on the status of the charge.

 - parameter id: id The ID of the charge.

 - throws: CloudRailError

 - returns: A charge resource for the provided ID.
 */
public func chargeWithIdentifier(id: String) throws -> CRCharge

public class CRCharge : CRSandboxObject {

    public var identifier: String!// ID of the newly generated charge
    public var amount: NSNumber!// amount that was charged
    public var currency: String!// currency in which the amount was charged
    public var source: CRCreditCard!// credit card that was charged
    public var created: NSNumber!// current state of the charge. Possible values are: 'pending',    
    public var status: String!// current state of the charge. Possible values are: 'pending', 'succeeded' or 'failed'
    public var refunded: NSNumber!// if the payment has been completely refunded or not
}

public class CRCreditCard : CRSandboxObject {

    //CostumerData
    public var firstName: String!
    public var lastName: String!
    public var address: CRAddress!
    public var number: String!

    // Card validation code
    public var cvc: String!

    // Values between 1 and 12
    public var expire_month: NSNumber!

    // Four digit expiration data
    public var expire_year: NSNumber!

    // Can have the following values: visa, mastercard, discover, amex
    public var type: String!
}

public class CRAddress : CRSandboxObject {

    public var country: String! // ID of the newly generated charge
    public var city: String! // City/Suburb/Town/Village
    public var state: String!
    public var line1: String!// Street address/PO Box/Company name
    public var line2: String!// Apartment/Suite/Unit/Building
    public var postalCode: String!
}
Example
do{
  let charge: CRCharge = try payment.chargeWithIdentifier("identifier")
} catch let error{
  print("An error: \(error)")
}

List Charges

Declaration
/**
     Receive a list of charges within a specified timeframe.

 - parameter from:       from Timestamp representing the start date for the list.
 - parameter to:         Timestamp representing the end date for the list.
 - parameter creditCard: Optionally the credit card information so it can be listed all the charges of this specific credit card.

 - throws: CloudRailError

 - returns: NSMutableArray of charge resources.
 */
public func listChargesFrom(from: Int, to: Int, creditCard: CRCreditCard) throws -> NSMutableArray

public class CRCharge : CRSandboxObject {

    public var identifier: String!// ID of the newly generated charge
    public var amount: NSNumber!// amount that was charged
    public var currency: String!// currency in which the amount was charged
    public var source: CRCreditCard!// credit card that was charged
    public var created: NSNumber!// current state of the charge. Possible values are: 'pending',    
    public var status: String!// current state of the charge. Possible values are: 'pending', 'succeeded' or 'failed'
    public var refunded: NSNumber!// if the payment has been completely refunded or not
}

public class CRCreditCard : CRSandboxObject {

    //CostumerData
    public var firstName: String!
    public var lastName: String!
    public var address: CRAddress!
    public var number: String!

    // Card validation code
    public var cvc: String!

    // Values between 1 and 12
    public var expire_month: NSNumber!

    // Four digit expiration data
    public var expire_year: NSNumber!

    // Can have the following values: visa, mastercard, discover, amex
    public var type: String!
}

public class CRAddress : CRSandboxObject {

    public var country: String! // ID of the newly generated charge
    public var city: String! // City/Suburb/Town/Village
    public var state: String!
    public var line1: String!// Street address/PO Box/Company name
    public var line2: String!// Apartment/Suite/Unit/Building
    public var postalCode: String!
}
Example
do{
  let current = NSDate.init().timeIntervalSince1970
  let aWeekAgo = current - 604800
  let charge: CRCharge = try payment.listChargesFrom(current, to: aWeekAgo, creditCard: creditCard)
} catch let error{
  print("An error: \(error)")
}

Completely Refund Charge

Declaration
/**
 Refund a previously made charge.

 - parameter id: The ID of the charge to be refunded.

 - throws: CloudRailError

 - returns: A refund resource.
 */
public func refundChargeWithIdentifier(id: String) throws -> CRRefund


public class CRRefund : CRSandboxObject {

    public var identifier: String!// The ID of the newly created refund
    public var amount: NSNumber!//  The amount that has been refunded
    public var created: NSNumber!// Timestamp representing the creation time of this refund
    public var currency: String!// The currency in which the refund was made
    public var chargeID: String!// Reference to the Charge that was refunded
    public var state: String!// Can have the following values: 'pending', 'succeeded' or 'failed'.
}

@end
Example
do{
  let refund : CRRefund = try payment.refundChargeWithIdentifier("identifier")
} catch let error{
  print("An error: \(error)")
}

Partially Refund Charge

Declaration
/**
 Refund a specified amount from a previously made charge.

 - parameter id:     The ID of the charge to be refunded.
 - parameter amount: The amount that shall be refunded.

 - throws: CloudRailError

 - returns: A refund resource.
 */
public func partiallyRefundChargeWithIdentifier(id: String, amount: Int) throws -> CRRefund

public class CRRefund : CRSandboxObject {

    public var identifier: String!// The ID of the newly created refund
    public var amount: NSNumber!//  The amount that has been refunded
    public var created: NSNumber!// Timestamp representing the creation time of this refund
    public var currency: String!// The currency in which the refund was made
    public var chargeID: String!// Reference to the Charge that was refunded
    public var state: String!// Can have the following values: 'pending', 'succeeded' or 'failed'.
}
Example
do{
  let refund : CRRefund = try payment.partiallyRefundChargeWithIdentifier("identifier", amount: 100)
} catch let error{
  print("An error: \(error)")
}

Get Refund

Declaration
/**
 Returns information about the refunds for a specific charge.

 - parameter id: The ID of the charge.

 - throws: CloudRailError

 - returns: A refund resource for the provided charge.
 */
public func refundWithIdentifier(id: String) throws -> CRRefund

public class CRRefund : CRSandboxObject {

    public var identifier: String!// The ID of the newly created refund
    public var amount: NSNumber!//  The amount that has been refunded
    public var created: NSNumber!// Timestamp representing the creation time of this refund
    public var currency: String!// The currency in which the refund was made
    public var chargeID: String!// Reference to the Charge that was refunded
    public var state: String!// Can have the following values: 'pending', 'succeeded' or 'failed'.
}
Example
do{
  let refund : CRRefund = try payment.refundWithIdentifier("identifier")
} catch let error{
  print("An error: \(error)")
}

Get Refunds for Charge

Declaration
/**
  Returns information about an existing refund. Mostly used to get an update on the status of the refund.

 - parameter id: The ID of the refund.

 - throws: CloudRailError

 - returns: A refund resource for the provided ID.
 */
public func refundsForChargeWithIdentifier(id: String) throws -> NSMutableArray
public class CRRefund : CRSandboxObject {

    public var identifier: String!// The ID of the newly created refund
    public var amount: NSNumber!//  The amount that has been refunded
    public var created: NSNumber!// Timestamp representing the creation time of this refund
    public var currency: String!// The currency in which the refund was made
    public var chargeID: String!// Reference to the Charge that was refunded
    public var state: String!// Can have the following values: 'pending', 'succeeded' or 'failed'.
}
Example
do{
  let refunds : CRRefund = try payment.refundWithIdentifier("identifier")
} catch let error{
  print("An error: \(error)")
}

Create Subscription Plan

Declaration
/**
       Creates a subscription plan which is required to use subscription based payments. The result of this method can be used together with 'createSubscription' in order to subscribe someone to your subscription plan.

       - parameter name:          The name for the subscription plan.
       - parameter amount:        The amount that is charged on a regular basis. A positive integer in the smallest currency unit (e.g. cents).
       - parameter currency:      A three-letter ISO code for currency.
       - parameter description:   A description for this subscription plan.
       - parameter interval:      Specifies the billing frequency together with interval_count. Allowed values are:day, week, month or year.

       - parameter intervalCount: Specifies the billing frequency together with interval. For example:interval_count = 2 and interval = "week" -> Billed every two weeks.

       - throws: CloudRailError

       - returns: the newly created subscription plan resource
       */
    public func createSubscriptionPlanWithName(name: String, amount: Int, currency: String, description: String, interval: String, intervalCount: Int) throws -> CRSubscriptionPlan


public class CRSubscriptionPlan : CRSandboxObject {

    public var identifier: String! // The ID of the subscription plan

    public var name: String! // The name of the subscription plan
    public var subscriptionDescription: String!// The description field of the subscription plan
    public var created: NSNumber!// Timestamp representing the creation time of this subscription plan
    public var amount: NSNumber!// The amount that is charged on a regular basis
    public var currency: String!// The currency in which the amount is charged
    public var interval: String!// The billing interval. Can have the following values: 'day', 'week', 'month' or 'year'.
    public var interval_count: NSNumber!// The billing frequency
}
Example
do{
  let subscriptionPlan : CRSubscriptionPlan = try payment.createSubscriptionPlanWithName("My subscription", amount: 500, currency: "USD", description: "myDescription", interval: "week", intervalCount: 2)
} catch let error{
  print("An error: \(error)")
}

List Subscription Plans

Declaration
/**
 Returns a list of all existing subscription plans.

 - throws: CloudRailError

 - returns: List of subscription plans.
 */
public func listSubscriptionPlans() throws -> NSMutableArray

public class CRSubscriptionPlan : CRSandboxObject {

    public var identifier: String! // The ID of the subscription plan

    public var name: String! // The name of the subscription plan
    public var subscriptionDescription: String!// The description field of the subscription plan
    public var created: NSNumber!// Timestamp representing the creation time of this subscription plan
    public var amount: NSNumber!// The amount that is charged on a regular basis
    public var currency: String!// The currency in which the amount is charged
    public var interval: String!// The billing interval. Can have the following values: 'day', 'week', 'month' or 'year'.
    public var interval_count: NSNumber!// The billing frequency
}
Example
do{
  let subscriptionPlans  = try payment.listSubscriptionPlans()
} catch let error{
  print("An error: \(error)")
}

Create Subscription

Declaration
/**
 Subscribes a new customer to an existing subscription plan.

 - parameter planID:      The ID of the subscription plan.
 - parameter name:        A name for the subscription.
 - parameter description: A description for the subscription.
 - parameter source:      The customer that shall be subscribed.

 - throws: CloudRailError

 - returns: The newly created subscription resource.
 */
public func createSubscriptionWithPlanID(planID: String, name: String, description: String, source: CRCreditCard) throws -> CRSubscription

public class CRCreditCard : CRSandboxObject {

    //CostumerData
    public var firstName: String!
    public var lastName: String!
    public var address: CRAddress!
    public var number: String!

    // Card validation code
    public var cvc: String!

    // Values between 1 and 12
    public var expire_month: NSNumber!

    // Four digit expiration data
    public var expire_year: NSNumber!

    // Can have the following values: visa, mastercard, discover, amex
    public var type: String!
}

public class CRAddress : CRSandboxObject {

    public var country: String! // ID of the newly generated charge
    public var city: String! // City/Suburb/Town/Village
    public var state: String!
    public var line1: String!// Street address/PO Box/Company name
    public var line2: String!// Apartment/Suite/Unit/Building
    public var postalCode: String!
}

public class CRSubscription : CRSandboxObject {

    public var identifier: String! // The subscription ID
    public var created: NSNumber! // Timestamp representing the time the subscription was created
    public var name: String! // The name of the subscription
    public var subscriptionDescription: String! // The description field of the subscription

    public var subscriptionPlanID: String!
    public var lastCharge: NSNumber!// Timestamp representing the last time a charge was made
    public var nextCharge: NSNumber!// Timestamp representing the next time a charge will be made

    public var creditCard: CRCreditCard! // Can have the following values: active or canceled.
    public var state: String!// Can have the following values: active or canceled.

}
Example
do{
  let creditCard = CRCreditCard.initWithCvc("", expireMonth:6, expireYear: 2021, number: "xxxxxxxxxxxxxxxx", type:"visa", firstName: "firstName", lastName:"lastName", address: address)

  let subscriptionPlans  = try payment.createSubscriptionWithPlanID("PlanID", name: "My Subscription", description: "My Subscription", source: creditCard)
} catch let error{
  print("An error: \(error)")
}

Cancel Subscription

Declaration
/**
 Cancel an active subscription.

 - parameter id: ID of the subscription that should be canceled.

 - throws: CloudRailError
*/
public func cancelSubscriptionWithIdentifier(id: String) throws
Example
do{
  try payment.cancelSubscriptionWithIdentifier("identifier")
} catch let error{
  print("An error: \(error)")
}

SMS

Introduction

This is a common interface for Services that provide the possibility to programmatically send SMS, e.g. for signup confirmations.

Implementing services

Function Overview

Functions

Send SMS

Declaration
/**
     Sends an SMS message, used like sendSMS("CloudRail", "+4912345678", "Hello from CloudRail").

 - parameter fromName: A alphanumeric sender id to identify/brand the sender. Only works in some countries.
 - parameter toNumber: The recipients phone number in E.164 format, e.g. +4912345678.
 - parameter content:  The message content. Limited to 1600 characters, messages > 160 characters are sent and charged as multiple messages.

 - throws: CloudRailError

 */
public func sendSmsFromName(fromName: String, toNumber: String, content: String) throws
Example
do{
  try sms.sendSmsFromName("CloudRail", toNumber: "+491234567890", content: "Hello from CloudRail")
} catch let error{
  print("An error: \(error)")
}

Email

Introduction

This is a common interface for Services that provide the possibility to programmatically send Emails, e.g. for signup confirmations.

Implementing services

Function Overview

Functions

Send Email

Declaration
/**
 Sends an email. Used like sendEmail("info@cloudrail.com", "CloudRail", Arrays.asList("foo@bar.com", "bar@foo.com"), "Welcome", "Hello from CloudRail", null, null, null).

 - parameter fromAddress:  Mandatory. The sender email address. Must normally be registered with the corresponding service.
 - parameter fromName:     Mandatory. The from name to be displayed to the recipient(s).
 - parameter toAddresses:  Mandatory. A list of recipient email addresses.
 - parameter subject:      Mandatory. The email's subject line.
 - parameter textBody:     The email's body plain text part. Either this and/or the htmlBody must be specified.
 - parameter htmlBody:     The email's body HTML part. Either this and/or the textBody must be specified.
 - parameter ccAddresses:  Optional. A list of CC recipient email addresses.
 - parameter bccAddresses: Optional. A list of BCC recipient email addresses.

 - throws: CloudRailError
*/
public func sendEmailFromAddress(fromAddress: String, fromName: String, toAddresses: NSMutableArray, subject: String, textBody: String, htmlBody: String, ccAddresses: NSMutableArray, bccAddresses: NSMutableArray) throws
Example
do{
  try email.sendEmailFromAddress("info@cloudrail.com", fromName: "CloudRail", toAddresses:NSMutableArray(array:  ["foo@bar.com","bar@foo.com"]), subject: "my subject", textBody: "text body", htmlBody: "Html body", ccAddresses: NSMutableArray(array:  ["foo@bar.com","bar@foo.com"]), bccAddresses: NSMutableArray(array:  ["foo@bar.com","bar@foo.com"]))
} catch let error{
  print("An error: \(error)")
}

Points of Interest

Introduction

This is a common interface for services that provide information about Points of Interest close to a given location. This location can be specified by passing latitude and longitude as well as a search radius. Furthermore, results can be limited by providing an optional search term or a list of categories.

Implementing services

Function Overview

Functions

Get Nearby POIs

Declaration
/**
 Returns a list of POIs that are close to the passed location and filters them by certain criteria.

 - parameter latitude:   The latitude of the target location
 - parameter longitude:  The longitude of the target location
 - parameter radius:     The search radius in metres
 - parameter searchTerm: Optional search term that has to be matched.
 - parameter categories: Optional list of categories. Available categories can be found in the main documentation.

 - throws: CloudRailError

 - returns: A list of POIs for the target location.
 */
public func nearbyPoisWithLatitude(latitude: Double, longitude: Double, radius: Int, searchTerm: String, categories: NSMutableArray) throws -> NSMutableArray

public class CRPOI : CRSandboxObject {    
    public var name: String! // The name of the POI
    public var imageURL: String! // A URL that can be used to display an image for this POI
    public var phone: String! // The phone number if there is one
    public var categories: NSMutableArray! // List of categories that apply to this POI
    public var location: CRLocation! // A Location object containing the location of the POI
}


public class CRLocation : CRSandboxObject {

    public var longitude: NSNumber!
    public var latitude: NSNumber!
}
Example
do{
  //Mannheim : 49.483927, 8.473272
  var points = try places.nearbyPoisWithLatitude(49.483927, longitude: 8.473272, radius: 3000, searchTerm: "Restaurant", categories: [])
} catch let error{
  print("An error: \(error)")
}

POI Categories

Use one or many of the below category keywords with the Points of Interest interface

  • airport
  • amusement_park
  • aquarium
  • bank
  • bar
  • beauty_salon
  • art_gallery
  • bakery
  • bicycle_store
  • book_store
  • bowling_alley
  • bus_station
  • cafe
  • car_dealer
  • car_rental
  • car_wash
  • casino
  • cemetery
  • church
  • clothing_store
  • convenience_store
  • courthouse
  • dentist
  • department_store
  • doctor
  • electronics_store
  • embassy
  • finance
  • fire_station
  • florist
  • food
  • funeral_home
  • furniture_store
  • gas_station
  • grocery_or_supermarket
  • gym
  • hardware_store
  • health
  • hindu_temple
  • hospital
  • jewelry_store
  • laundry
  • lawyer
  • library
  • locksmith
  • mosque
  • movie_theater
  • museum
  • night_club
  • parks
  • parking
  • pet_store
  • pharmacy
  • physiotherapist
  • police
  • post_office
  • real_estate_agency
  • restaurant
  • rv_park
  • school
  • shoe_store
  • shopping_mall
  • spa
  • stadium
  • synagogue
  • taxi_stand
  • train_station
  • travel_agency
  • university
  • veterinary_care
  • zoo

Advanced Request

The methods above are chosen to reflect most commonly used functionalities and thus those that all services implementing an interface have in common. It follows that the APIs of the services CloudRail integrates with offer more, service-specific functionality that is missing from CloudRail. To mitigate this, the advanced request functionality was introduced. It allows a developer to specify the raw HTTP request against an API and thus access all of its functionality. To be more than just another HTTP Client, CloudRail supports the developer by taking care of authentication and error checking.

Supported services

Currently, the advanced request function is present on all services implementing the CloudStorage interface and those implementing the Profile interface. More services will follow soon.

Example

We want to list all shared folders of a Dropbox account and know through the Dropbox API documentation that this functionality is supported by Dropbox (https://www.dropbox.com/developers/documentation/http/documentation#sharing-list_folders). Yet, it is not supported by the CloudRail Dropbox service so we use advanced request. The example assumes that you are already familiar with the installation and intialization of a CloudRail service integration.

// Initialize like usual
CRCloudRail.setAppKey("[CloudRail key]")
let dropbox = Dropbox.init(clientId: "[clientId]", clientSecret: "[clientSecret]")

// Specify the URL of the Dropbox API endpoint, the base URL is prepended by default
let req = CRAdvancedRequestSpecification.init(url: "/sharing/list_folders")

// Set the HTTP request method to POST
req.method = "POST"

// Specify the body and let it be converted to JSON
let body = [
  "limit": 100
]
req.setBodyStringifyJson(body)

// Specify the headers
let headers = [
  "Content-Type": "application/json"
]
req.headers = headers

// Execute the request, CloudRail will start the authentication flow if necessary
// and append the authorization header.
// The response is checked for errors.
let res = dropbox.advancedRequest(req)

// Extract the parsed response body
let jsonRes = res.getBodyJsonParsed()

Specification

All supported services have an advancedRequest method:

public func advancedRequest(specification: CRAdvancedRequestSpecification) throws -> CRAdvancedRequestResponse

The AdvancedRequestSpecification looks like this:

public class CRAdvancedRequestSpecification : CRSandboxObject {
    public var url: String
    public var method: String
    public var body: NSInputStream
    public var headers: NSMutableDictionary
    public var appendAuthorization: NSNumber
    public var checkErrors: NSNumber
    public var appendBaseUrl: NSNumber

    init(url: String)

    public func setBodyAsString(body: String)
    public func setBodyStringifyJson(body: AnyObject)
    public func setBodyStringifyXml(body: NSDictionary)
}

The AdvancedRequestResponse looks like this:

public class CRAdvancedRequestResponse : CRSandboxObject {
    public var body: NSInputStream
    public var headers: NSDictionary
    public var status: NSNumber

    public func bodyAsString() -> String
    public func bodyJsonParsed() -> AnyObject
    public func bodyXmlParsed() -> NSDictionary
}

Limitations

The requests are facilitated by prepending a Base URL, adding authorization and doing error checking. This assumes similar behavior in those regards of all API methods. Yet sometimes, this is not the case. You might have to disable authentication and do it on your own, e.g. because insufficient scopes are requested. You might have to disable error checking or do additional checking because the defaults are wrong or not sufficient. You might have to disable prepeding the base URL because a certain API endpoint has a different one. Do read up on each service in the Services section to learn about what base URL is prepended, what authorization appending does and which errors are caught.