iOS Library/SDK


QuickStart

Catapush iOS sdk  is available through CocoaPods

To install it, simply add the following line to your Podfile:

 

pod "catapush-ios-sdk-pod"

 

Catapush SDK

Import CatapushHeaders.h into your application delegate as follows:

#import "CatapushHeaders.h"

Get your App Key from Catapush Dashboard and insert it together with a couple of credentials (you have to create them via API of from the Catapush Dashboard) into your application delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    [Catapush setAppKey:@"YOUR_APP_KEY"];

    // Register for push notifications Standard or VoIP based on capabilites setting in Xcode Project
    [Catapush registerUserNotification:self voIPDelegate:nil];

    [Catapush startWithIdentifier: @"test" andPassword:@"test"];

    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [Catapush applicationDidEnterBackground:application];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    [Catapush applicationWillEnterForeground:application];
}
The method registerUserNotification/2 requests registration for remote notifications. If VoIP background mode in an app is enabled in XCode capabilites, then the method requests a registration for VoIP notifications.
Note: Catapush DOES register push notifications for you, so DO NOT register push notifications by calling instance method registerUserNotificationSettings/1 of UIApplication.

Enabling Voice Over IP Push Notifications (PushKit)

For the maximum level of reliability you need to use the Voice Over IP Push Notifications (PushKit framework), this guarantee high priority push and the ability to start the application also if is inactive. To use this type of notifications your APP must contains a Voip functionality, if your APP doesn't already has a Voip functionality included you can easly add a Voip customer support channel. With this feature included your APP will pass the Apple review process for publication on the Apple store.
To use Voip push notifications you have to enable this type of notifications in the capabilites section in your XCode project:
enable voip capabilities
enable voip capabilities
If the VoIP capability is enabled, Catapush library will automatically display an alert message and play a default sound when a notification is received (you don't need to write code for showing alert message).
If you want to use standard notifications instead just select Remote Notifications (and unselect Voip). Please note that "standard Push notifications" are less reliable than Voip notifications and should be used only in specific cases, you should always use Voip notifications to guarantee the highest level of reliability.

The 2nd argument of the method registerUserNotification/2 is a VoIPNotificationDelegate delegate. The protocol VoIPNotificationDelegate has one method didReceiveIncomingPushWithPayload:(PKPushPayload *)payload called when a notifications is received. If you want you can implement this method and write your custom code, in this case Catapush library will not display any alert or play a sound when a notification is received.

Certificate, App Id, and Entitlements

These are pre-requisites for setting up VoIP with Catapush.
  • Make sure your app has an explicit app id and push entitlements in Apple's Developer Portal.
  • Create a VoIP Push Certificate. This can be used for the development and production environment.
voip cert
  • Import the VoIP Push Certificate into Keychain Access and export as a .p12 file.
  • Upload the exported .p12 file into your Catapush Application ("Platform" menu item) in the Catapush Dashboard.

Standard Push Notifications

If you want to use standard push notifications you must declare the following methods.
Catapush library will injects the required code in these methods in order to intercept their calls when a "standard notifications" is received, the injected code will handle incoming push notifications. You can insert custom code if you have specific needs or you can leave them empty.
# pragma mark - Must declare in order to let AOP to inject catapush library code
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    // User code, can be empty
}

# pragma mark - Must declare in order to let AOP to inject catapush library code
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    // User code, can be empty
}

# pragma mark - Must declare in order to let AOP to inject catapush library code
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    // User code, can be empty
}

# pragma mark - Must declare in order to let AOP to inject catapush library code
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    // User code, can be empty
}

Events Handling

In order to receive events, you have to setup two delegates CatapushDelegate and MessagesDispatchDelegate, for instance your App Delegate itself:

@interface AppDelegate () <CatapushDelegate, MessagesDispatchDelegate>

and then for instances in your application delegate application:didFinishLaunchingWithOption:

[Catapush setupCatapushStateDelegate:self andMessagesDispatcherDelegate:self];

CatapushDelegate handles connection events, notifying the connection state, and MessagesDispatchDelegate deliver Messages to your App Authentication

CatapushDelegate is in charge of notifying the state of the connection or any errors related with the Library

If connection is successfully, this delegate is triggered:

- (void)catapushDidConnectSuccessfully:(Catapush *)catapush
{
    UIAlertView *connectedAV = [[UIAlertView alloc] initWithTitle:@"Connected"
                                                          message:@"Catapush Connected!" delegate:self
                                                cancelButtonTitle:@"Ok" otherButtonTitles:nil];
    [connectedAV show];
}

Error handling comes with this delegate:

- (void)catapush:(Catapush *)catapush didFailOperation:(NSString *)operationName withError:(NSError *)error
{

    if ([error.domain isEqualToString:CATAPUSH_ERROR_DOMAIN]) {

    switch (error.code) {
        case WRONG_AUTHENTICATION:
            break;
        case INVALID_APP_KEY:
            break;
        case USER_NOT_FOUND:
            break;
        case GENERIC:
            break;
        default:
            break;
    }

    }

    NSString *errorMsg = [NSString stringWithFormat:@"The operation %@ is failed with error:\n%@", operationName, [error localizedDescription]];

    UIAlertView *flowErrorAlertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                             message:errorMsg
                                                            delegate:self
                                                   cancelButtonTitle:@"Ok"
                                                   otherButtonTitles:nil];
    [flowErrorAlertView show];

}

Receiving Messages

MessagesDispatchDelegate is the delegate in charge of messages dispatching. Messages are represented by a MessageIP object, and arrive in this delegate:

-(void)libraryDidReceiveMessageIP:(MessageIP *)messageIP 
{ NSLog(@"Did receive IP Message with identifier: %@ and body: %@", messageIP.identifier, messageIP.body); }

Reading Messages

When you consume the received Messages (you show it on the screen), you have to mark it as readed:

-(void)libraryDidReceiveMessageIP:(MessageIP *)messageIP 
{ NSLog(@"Did receive IP Message with identifier: %@ and body: %@", messageIP.identifier, messageIP.body); UIAlertView *connectedAV = [[UIAlertView alloc] initWithTitle:@"MyApp" message:messageIP.body delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil]; [connectedAV show]; [MessageIP sendMessageReadNotification:messageIP]; }

Sending Messages

You can send messages to Catapush server using the following method:
[Catapush sendMessageWithText:text];
and you can monitor the status of the message delivery with new two optional methods of the MessagesDispatchDelegate protocol:
- (void)libraryDidSendMessage:(MessageIP *)message;
- (void)libraryDidFailToSendMessage:(MessageIP *)message;
the delivery status of a message is stored in the status property of MessageIP class. It's possible value are list by the enum:
typedef NS_ENUM(NSInteger, MESSAGEIP_STATUS)
{
    MessageIP_NOT_READ = 0,
    MessageIP_READ = 1,
    MessageIP_READ_SENT_ACK = 2,
    MessageIP_NOT_SENT = 3,
    MessageIP_SENT = 4,
    MessageIP_SENDING = 5
};
In case a delivery of message fails you can re-send the message using its messageID:
+ (MessageIP *)sendMessageWithMessageId:(NSString *) messageId;

Advanced

Let Library knows when user read message in your own View invoking this method:

[MessageIP sendMessageReadNotification:messageIP];

You can always query the current connection state of the Library by using an Observer over the connection state, with the following method:

[[NSNotificationCenter defaultCenter] addObserver:self 
                                         selector:@selector(checkLibraryStatus)
                                             name:kCatapushStatusChangedNotification
                                           object:nil];

is possible to get the current connection state with:

[Catapush status];

that returns an enum of states:

  • DISCONNECTED
  • CONNECTING
  • CONNECTED

in your selector as the one declared above:

- (void)checkLibraryStatus 
{
NSString *statusString; switch ([Catapush status]) { case CONNECTED: statusString = @"Connected"; break; case DISCONNECTED: statusString = @"Disconnected"; break; case CONNECTING: statusString = @"Connecting.."; break; } NSLog(@"%@", statusString); }

Messages Managers

Catapush iOS SDK manages the messages using the power of CoreData Framework. This allow an easy integration of the library and management of the MessageIP object life-cicle.

CatapushCoreData exposes:

  • managedObjectContext
  • managedObjectModel
  • persistentStoreCoordinator

These three objects can be used with the protocol.

For example to retrieve all messages stored and their changes, set up the NSFetchedResultsControllerDelegate with the desidered NSPredicate (see below).

@property (nonatomic, strong) NSFetchedResultsController *fetchedResultsController; //handles all Messages
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;

- (void)perfomFetch 
{ self.fetchedResultsController.delegate = self; NSError *error; BOOL success = [self.fetchedResultsController performFetch:&error]; //Now all messages are stored in [self.fetchedResultsController objectAtIndexPath:indexPath]; } - (NSFetchedResultsController *)fetchedResultsController
{ if (!_fetchedResultsController) { NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MessageIP"]; request.predicate = nil; request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"sentTime" ascending:YES]]; _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil]; } return _fetchedResultsController; } - (NSManagedObjectContext *)managedObjectContext
{ if (!_managedObjectContext) { _managedObjectContext = [CatapushCoreData managedObjectContext]; } return _managedObjectContext; }

then observe the MessageIP changes:

  • Insertion
  • Updating
  • Deletion

with the NSFetchedResultsControllerDelegate methods:

#pragma mark - NSFetchedResultsControllerDelegate

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
{ //If needed, prepare for content changes } - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{ switch(type) { case NSFetchedResultsChangeInsert: //New object fetched break; case NSFetchedResultsChangeDelete: //Object deleted break; default: break; } } - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { switch(type) { case NSFetchedResultsChangeInsert: //New object fetched break; case NSFetchedResultsChangeDelete: //Object deleted break; case NSFetchedResultsChangeUpdate: //Object updated break; case NSFetchedResultsChangeMove: //Object changes index in the array break; } } - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { //After the changes of the fetched content }

Using NSFetchedResultsController is easy to fetch messages that satisfy a condition. For Example when creating NSFetchRequest to fetch all messages just set:

request.predicate = nil;

i.e.

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MessageIP"];
request.predicate = nil;
request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"sentTime" ascending:YES]];

if you need the unread messages just write:

request.predicate = [NSPredicate predicateWithFormat:@"status = %i", MessageIP_NOT_READ];

i.e.

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MessageIP"];
request.predicate = [NSPredicate predicateWithFormat:@"status = %i", MessageIP_NOT_READ];
request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"sentTime" ascending:YES]];

When the objects that satisfy the defined NSPredicate you will be notifies in the NSFetchedResultsControllerDelegate methods as shown above.

 

Catapush sdk iOS App Example

This project shows how quickly Catapush iOS SDK can be integrated into your current app to receive Catapush messages and display them with a customizable bubble layout.

catapush_screen_shot.jpg

Usage

  1. git clone https://github.com/Catapush/catapush-ios-sdk-example.git
  2. cd catapush-ios-sdk-example
  3. pod install
  4. open catapush-ios-sdk-example.xcworkspace
  5. Get your App Key from Catapush Dashboard and insert it together with a couple of credentials of your choice into your application delegate application:didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{
    [Catapush setAppKey:@"YOUR_APP_KEY"];

    // Register for push notifications Standard or VoIP based on capabilites setting in Xcode Project
    [Catapush registerUserNotification:self voIPDelegate:nil];

    [Catapush startWithIdentifier: @"test" andPassword:@"test"];

    return YES;
}
  1. Run the app
  2. Back to your Catapush Dashboard and send some important message.

FAQ

Which is the minimum supported iOS API?

Catapush supports iOS 7.0 and greater.

What's the size of the library?

The contribution of the Catapush static library to IPA size is 650KB.
The size of the static library archive file, compiled with ENABLE_BITCODE = 1, is 60MB (it included differents architecture object files).

There is an example project available?

You can find example projects in Swift and Objective-C