iOS SDK - Push notifications

Push Notification Activation

Push Notification Activation

i. Setup Apple Push Notification Services

Prerequisites for Apple Push Notification Services Setup

The Importance of Setting your App as in “Production” or in “Development”

When creating or editing an app on RadiumOne Connect you can set the status of the app to either “Production” or “Development”. “Production” status for an app is considered to be a live app that is in the hands of real users and will have notifications and other data running on live servers. A “Development” status for an app is one that you are still performing testing on and will not be viewed by any real-life audiences because it will stay on test servers.

In the context of push notifications, it is important to know this difference because Apple will treat these two servers separately. Also device tokens for “Development” will not work on “Production” and vice versa. We recommend a Development app version and Production app version for your app on RadiumOne Connect to keep Push SSL certificates separate for each. You can also continue testing and experimenting on one app without worrying about it affecting your live app audience in any way.

iOS Developer Program Enrollment

This doc assumes that you are enrolled in the iOS Developer Program. If you are not, please enroll here. Being in the Apple Developer Program is a required component to have your iOS app communicate with the RadiumOne Connect service for push notifications and is necessary for the next step of setting up your app with the Apple Push Notification Service (APNs). It is also essential that you have “Team Agent” role access in the iOS Developer Program to complete this process.

Configuring your App for Apple Push Notifications

Apple Developer Members Center

Make sure you are logged into the Apple Developer Members Center. Once you are logged in you can locate your application in the “Identifiers” folder list.

Files in Xcode project

Registered App ID

If you have not registered an App ID yet it is important that you do so now. You will need to click the “+” symbol, fill out the form, and check the “Push Notifications” checkbox. Please keep in mind it is possible to edit these choices after the App ID is registered.

Files in Xcode project Files in Xcode project

You can expand the application and when doing so you will see two settings for push notifications. They will have either yellow or green status icons like here:

Files in Xcode project

You will need to click Edit to continue. If the Edit button is not visible it is because you do not have “Team Agent” role access. This role is necessary for getting an SSL certificate.

Creating an SSL Certificate

To enable the Development or Production Push SSL Certificate please click Edit. (It is important to note that each certificate is limited to a single app, identified by its bundle ID and limited to one of two environments, either Development or Production. Read more info here.)

Files in Xcode project

You will see a Create Certificate button, after clicking it you will see the “Add iOS Certificate Assistant”. Please follow the instructions presented in the assistant which includes launching the “Keychain Access” application, generating a “Certificate Signing Request (CSR)”, generating an SSL Certificate, etc.

If you follow the assistant correctly, after downloading and opening the SSL Certificate you should have it added under “My Certificates” or “Certificates” in your “Keychain Access” application. Also when you are returned to the Configure App ID page the certificate should be badged with a green circle and the label “Enabled”.

Files in Xcode project

Exporting the SSL Certificate

If not already in the “Keychain Access” app that contains your certificate, please open it and select the certificate that you just added. Once you select the certificate go to File > Export Items and export it as a Personal Information Exchange (.p12) file. When saving the file be sure to use the Personal Information Exchange (.p12) format.

Files in Xcode project

Emailing your SSL certificate

After downloading your 2 certificates (one for production, one for development), please send them to your RadiumOne account manager (with certificate passwords if you choose to add any).

 

ii. Initialization

Setup your App Delegate

(Only for Objective C code)

#import "R1SDK.h"
#import "R1Emitter.h"
#import "R1Push.h"
#import "R1WebCommand.h" // required for rich push
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  R1SDK *sdk = [R1SDK sharedInstance];

  // Initialize SDK
  sdk.applicationId = @"Application ID";  //Ask your RadiumOne contact for an app id

  // Initialize Push Notification
  sdk.clientKey = @"Your Client Key";  //Ask your RadiumOne contact for a client key
  [[R1Push sharedInstance] handleNotification:[launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey]
    applicationState: application.applicationState];
  [[R1Push sharedInstance] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
      UIRemoteNotificationTypeSound |
      UIRemoteNotificationTypeAlert)];

  // Start SDK
  [sdk start];
  return YES;
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    let sdk = R1SDK.sharedInstance();

    // Initialize Anlaytics
    sdk.applicationId = "Application ID";  //Ask your RadiumOne contact for an app id

    // Initialize Push Notification
    sdk.clientKey = "Your Client Key";  //Ask your RadiumOne contact for a client key

    R1Push.sharedInstance().delegate = self;
    var remoteNotificationInfo: NSDictionary? = nil
    if launchOptions != nil {
        remoteNotificationInfo = (launchOptions![UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary)!;
    }

    R1Push.sharedInstance().handleNotification(remoteNotificationInfo as? [NSObject : AnyObject], applicationState: application.applicationState);
    R1Push.sharedInstance().registerForRemoteNotificationTypes([.Alert ,.Badge ,.Sound]);

    // Start SDK
    sdk.start();

    return true
}

Register for Remote Notifications

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
  [[R1Push sharedInstance] registerDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
  [[R1Push sharedInstance] failToRegisterDeviceTokenWithError:error];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
  [[R1Push sharedInstance] handleNotification:userInfo applicationState:application.applicationState];
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    R1Push.sharedInstance().registerDeviceToken(deviceToken);
}

func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
    R1Push.sharedInstance().failToRegisterDeviceTokenWithError(error);
}

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    R1Push.sharedInstance().handleNotification(userInfo, applicationState: application.applicationState);
}

Push is disabled by default. You can enable it in the application:didFinishLaunchingWithOptions method or later.

[[R1Push sharedInstance] setPushEnabled:YES];
R1Push.sharedInstance().pushEnabled = true;

NOTE: If you enabled it in the application:didFinishLaunchingWithOptions method, the Push Notification AlertView will be showed at first application start.

iii. Rich Push Initialization

Rich Push Notifications send a URL that opens in a WebView upon user response to a system notification. No set up is required for this feature.

Please note that iOS 9 devices require use of HTTPS. iOS 8 and previous versions still support HTTP. Please ensure that you send HTTPS if iOS 9 devices may receive the message.

iv. Deep Link Initialization

Deep linking Push Notifications open up a designated view in an application upon user response to a system notification. To properly handle deep link push receipts, please read Apple's documentation:https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html#//apple_ref/doc/uid/TP40007072-CH6-SW10http://wiki.akosma.com/IPhone_URL_Schemes

v. Segment your Audience

You can specify Tags for R1 Connect SDK to send Push Notifications to certain groups of users.

The maximum length of a Tag is 128 characters.

R1 Connect SDK saves Tags. You do not have to add Tags every time the application is launched.

Add a new Tag

[[R1Push sharedInstance].tags addTag:@"NEW TAG"];
R1Push.sharedInstance().tags.addTag("NEW TAG");

Add multiple Tags

[[R1Push sharedInstance].tags addTags:@[ @"NEW TAG 1", @"NEW TAG 2" ]];
R1Push.sharedInstance().tags.addTags(["NEW TAG 1", "NEW TAG 2"]);

Remove existing Tag

[[R1Push sharedInstance].tags removeTag:@"EXIST TAG"];
R1Push.sharedInstance().tags.removeTag("EXIST TAG");

Remove multiple Tags

[[R1Push sharedInstance].tags removeTags:@[ @"EXIST TAG 1", @"EXIST TAG 2" ]];
R1Push.sharedInstance().tags.removeTags([ "EXIST TAG 1", "EXIST TAG 2" ]);

Replace all existing Tags

[R1Push sharedInstance].tags.tags = @[ @"NEW TAG 1", @"NEW TAG 2" ];

or

[[R1Push sharedInstance].tags setTags:@[ @"NEW TAG 1", @"NEW TAG 2" ]];
R1Push.sharedInstance().tags.tags = ["NEW TAG 1", "NEW TAG 2"];

Get all Tags

NSArray *currentTags = [R1Push sharedInstance].tags.tags;
let currentTags = R1Push.sharedInstance().tags.tags;

Automatically created Tags

date_of_launch_dd_mm_yyyy: Replace dd_mm_yyyy with the date you want to target. Date is in your account timezone.
one_time_app_users: Users who have only launched the app once

Automatically created Segments

Lapsed Users > 7 Days
Lapsed Users > 14 Days
Lapsed Users > 21 Days
Lapsed Users > 30 Days

vi. Inbox Integration

The Inbox provides an easy interface to house past rich-push messages sent to your users so they can still be visible to users that have disabled push messaging or who want to come back to them later.

If you want to enable inbox functionality, you need to use R1Inbox class and import R1Inbox.h header at the top of your class file (Only for Objective C code):

#import "R1Inbox.h"

If you want to add some label or button with count of unread or total Inbox messages, you should implement -(void) inboxMessageUnreadCountChanged or -(void) inboxMessagesDidChanged (func inboxMessageUnreadCountChanged() orfunc inboxMessagesDidChanged() for swift) methods from R1InboxMessagesDelegate protocol in your class. After that, add your class as delegate to [R1Inbox sharedInstance].messages (R1Inbox.sharedInstance().messages for swift).

- (void) addInboxMessagesDelegate
{
    [[R1Inbox sharedInstance].messages addDelegate:self];
}

-(void) inboxMessageUnreadCountChanged
{
    NSString *btnTitle = [NSString stringWithFormat:@"Inbox (%lu unread)", (unsigned long)[R1Inbox sharedInstance].messages.unreadMessagesCount];

    [self.inboxButton setTitle:btnTitle forState:UIControlStateNormal];
}
func addInboxMessagesDelegate() {
  R1Inbox.sharedInstance().messages.addDelegate(self);
}

func inboxMessageUnreadCountChanged() {
  let btnTitle = String.init(format: "Inbox unread cound: %d", R1Inbox.sharedInstance().messages.unreadMessagesCount);
  inboxButton?.setTitle(btnTitle, forState: .Normal);
}

Do not forget to remove your class from delegates when your class gets deallocated:

- (void) dealloc
{
    [[R1Inbox sharedInstance].messages removeDelegate:self];
    //...
}
deinit {
    R1Inbox.sharedInstance().messages.removeDelegate(self);
    //...
}

To display the list of Inbox messages, you should create your own ViewController to provide required customization. In this case, this screen would not look foreign to your application.

You can see the sample of Inbox implementation in DemoApplication project in files R1SampleInboxTableViewCell.h,R1SampleInboxTableViewCell.m, R1SampleInboxViewController.h, R1SampleInboxViewController.m (for Objective C) and in DemoApplicationSwift project in files R1SampleInboxTableViewCell.swift, R1SampleInboxViewController.swift (for swift)

R1SampleInboxTableViewCell.h

#import <UIKit/UIKit.h>

@class R1InboxMessage;

@interface R1SampleInboxTableViewCell : UITableViewCell

// Sets or Gets R1InboxMessage object and configures cell for it
@property (nonatomic, strong) R1InboxMessage *inboxMessage;

- (id) initWithReuseIdentifier:(NSString *)reuseIdentifier;

// Calculates the height of the cell
+ (CGFloat) heightForCellWithInboxMessage:(R1InboxMessage *) inboxMessage cellWidth:(CGFloat) cellWidth;

@end

R1SampleInboxTableViewCell.m

#import "R1SampleInboxTableViewCell.h"
#import "R1Inbox.h"

@interface R1SampleInboxTableViewCell ()

@property (nonatomic, strong) UIView *unreadMarker;
@property (nonatomic, strong) UILabel *alertLabel;

@property (nonatomic, strong) NSDateFormatter *dateFormatter;

@end

@implementation R1SampleInboxTableViewCell

- (id) initWithReuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier];
    if (self)
    {
        self.alertLabel = [[UILabel alloc] initWithFrame:CGRectZero];
        self.alertLabel.numberOfLines = 0;
        self.alertLabel.lineBreakMode = NSLineBreakByWordWrapping;
        [self.contentView addSubview:self.alertLabel];

        self.unreadMarker = [[UIView alloc] initWithFrame:CGRectZero];
        self.unreadMarker.layer.cornerRadius = 3;
        self.unreadMarker.backgroundColor = [UIColor blueColor];
        [self.contentView addSubview:self.unreadMarker];

        self.textLabel.font = [UIFont boldSystemFontOfSize:14];
        self.alertLabel.font = [UIFont systemFontOfSize:14];

        self.detailTextLabel.textAlignment = NSTextAlignmentRight;

        self.dateFormatter = [[NSDateFormatter alloc] init];
        [self.dateFormatter setDateStyle:NSDateFormatterShortStyle];
        [self.dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
    }
    return self;
}

// Configures the cell for displaying Inbox Message
- (void) setInboxMessage:(R1InboxMessage *)inboxMessage
{
    if (_inboxMessage == inboxMessage)
    {
        [self configureUnreadMarker];
        return;
    }

    _inboxMessage = inboxMessage;

    self.textLabel.text = inboxMessage.title;
    self.alertLabel.text = inboxMessage.alert;

    self.detailTextLabel.text = [self.dateFormatter stringFromDate:inboxMessage.createdDate];
    [self configureUnreadMarker];

    [self setNeedsLayout];
}

// Shows or hides unread marker view
- (void) configureUnreadMarker
{
    if ([self.unreadMarker isHidden] != _inboxMessage.unread)
        return;

    [self.unreadMarker setHidden:!_inboxMessage.unread];
}

- (void) layoutSubviews
{
    [super layoutSubviews];

    self.unreadMarker.frame = CGRectMake(4, (self.contentView.bounds.size.height - 6)/2, 6, 6);

    self.detailTextLabel.frame = CGRectMake(0, 0, self.contentView.bounds.size.width-10, 20);

    if (self.textLabel.text == nil)
    {
        self.alertLabel.frame = CGRectMake(15, 15, self.contentView.bounds.size.width-20, self.contentView.bounds.size.height-20);
    }else
    {
        self.textLabel.frame = CGRectMake(15, 15, self.contentView.bounds.size.width-20, 20);
        self.alertLabel.frame = CGRectMake(15, 35, self.contentView.bounds.size.width-20, self.contentView.bounds.size.height-45);
    }
}

// Calculates the height of the cell
+ (CGFloat) heightForCellWithInboxMessage:(R1InboxMessage *) inboxMessage cellWidth:(CGFloat) cellWidth
{
    CGFloat height = 25;

    if (inboxMessage.title != nil)
        height += 20;

    if (inboxMessage.alert != nil)
    {
        if ([inboxMessage.alert respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)])
        {
            NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init];
            paragraph.lineBreakMode = NSLineBreakByWordWrapping;

            NSDictionary *attributes = @{NSFontAttributeName : [UIFont systemFontOfSize:14],
                                         NSParagraphStyleAttributeName: paragraph};

            height += [inboxMessage.alert boundingRectWithSize:CGSizeMake(cellWidth-20, 100)
                                                       options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                                    attributes:attributes
                                                       context:nil].size.height;
        }else
        {
            height += [inboxMessage.alert sizeWithFont:[UIFont systemFontOfSize:14]
                                     constrainedToSize:CGSizeMake(cellWidth-20, 100)
                                         lineBreakMode:NSLineBreakByWordWrapping].height;
        }

        height += 1;
    }

    if (height < 50)
        return 50;

    return height;
}

@end

R1SampleInboxViewController.h

#import <UIKit/UIKit.h>
#import "R1Inbox.h"

@protocol R1SampleInboxViewControllerDelegate;

@interface R1SampleInboxViewController : UITableViewController <R1InboxMessagesDelegate>

@property (nonatomic, assign) id<R1SampleInboxViewControllerDelegate> inboxDelegate;

- (id) initInboxViewController;

@end

@protocol R1SampleInboxViewControllerDelegate <NSObject>

- (void) sampleInboxViewControllerDidFinished:(R1SampleInboxViewController *) sampleInboxViewController;

@end

R1SampleInboxViewController.m

#import "R1SampleInboxViewController.h"
#import "R1SampleInboxTableViewCell.h"
#import "R1Inbox.h"

@interface R1SampleInboxViewController ()

@property (nonatomic, strong) R1InboxMessages *inboxMessages;

@end

@implementation R1SampleInboxViewController

// Initialize UITableViewController
- (id) initInboxViewController
{
    self = [super initWithStyle:UITableViewStylePlain];
    if (self)
    {
        self.inboxMessages = [R1Inbox sharedInstance].messages;

        [self updateTitle];

        self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
                                                                                              target:self action:@selector(closeInboxViewController)];
    }
    return self;
}

// Called when user presses 'Done' button
- (void) closeInboxViewController
{
    [self.inboxDelegate sampleInboxViewControllerDidFinished:self];
}

// Updates the title of ViewController with number of unread messages
- (void) updateTitle
{
    if (self.inboxMessages.unreadMessagesCount == 0)
        self.navigationItem.title = @"Inbox";
    else
        self.navigationItem.title = [NSString stringWithFormat:@"Inbox (%lu unread)", (unsigned long)self.inboxMessages.unreadMessagesCount];
}

- (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [self updateTitle];

    // Add this view controller to the list of delegates when it appears
    [self.inboxMessages addDelegate:self];
}

- (void) viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    // Remove this view controller from the list of delegates when it disappears
    [self.inboxMessages removeDelegate:self];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Returns the total number of Inbox messages
    return self.inboxMessages.messagesCount;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Returns the calculated height of the cell for R1InboxMessage object in row
    return [R1SampleInboxTableViewCell heightForCellWithInboxMessage:[self.inboxMessages.messages objectAtIndex:indexPath.row]
                                                           cellWidth:self.tableView.frame.size.width];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    R1SampleInboxTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if (cell == nil)
    {
        cell = [[R1SampleInboxTableViewCell alloc] initWithReuseIdentifier:@"Cell"];
    }

    // Sets up the cell for displaying R1InboxMessage object
    cell.inboxMessage = [self.inboxMessages.messages objectAtIndex:indexPath.row];

    return cell;
}

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    R1InboxMessage *message = [self.inboxMessages.messages objectAtIndex:indexPath.row];

    // Shows Inbox message when user interacts to the cell
    [[R1Inbox sharedInstance] showMessage:message
                           messageDidShow:^{
                               [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
                           }];
}

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewCellEditingStyleDelete;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    R1InboxMessage *message = [self.inboxMessages.messages objectAtIndex:indexPath.row];

    [self.inboxMessages deleteMessage:message];
}

#pragma mark - R1InboxMessagesDelegate methods

// This method called when the list of Inbox messages gets updated
- (void) inboxMessagesWillChanged
{
    [self.tableView beginUpdates];
}

// This method called when any item in the list of Inbox messages gets changed (modified, inserted or removed)
- (void) inboxMessagesDidChangeMessage:(R1InboxMessage *) inboxMessage
                               atIndex:(NSUInteger) index
                         forChangeType:(R1InboxMessagesChangeType)changeType
                              newIndex:(NSUInteger) newIndex
{
    switch (changeType)
    {
        case R1InboxMessagesChangeInsert:
            [self.tableView insertRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:index inSection:0] ]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
        case R1InboxMessagesChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:@[ [NSIndexPath indexPathForRow:index inSection:0] ]
                                  withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
        case R1InboxMessagesChangeUpdate:
            ((R1SampleInboxTableViewCell *)[self.tableView cellForRowAtIndexPath: [NSIndexPath indexPathForRow:index inSection:0] ]).inboxMessage = [self.inboxMessages.messages objectAtIndex:index];

            break;

        default:
            break;
    }
}

// This method called when the changes to list of Inbox messages are over
- (void) inboxMessagesDidChanged
{
    [self.tableView endUpdates];
}

// This method called when the number of unread Inbox messages gets changed
- (void) inboxMessageUnreadCountChanged
{
    [self updateTitle];
}

@end

R1SampleInboxViewController.swift

import UIKit

protocol R1SampleInboxViewControllerDelegate {
    func sampleInboxViewControllerDidFinished(sampleInboxViewController: R1SampleInboxViewController);
}

class R1SampleInboxViewController: UITableViewController, R1InboxMessagesDelegate {

    var inboxMessages: R1InboxMessages?
    var inboxDelegate: R1SampleInboxViewControllerDelegate?;

    override func viewDidLoad() {
        super.viewDidLoad()

        inboxMessages = R1Inbox.sharedInstance().messages;

        updateTitle();
    }

    func updateTitle() {
        if (inboxMessages?.unreadMessagesCount == 0) {
            navigationItem.title = "Inbox";
        } else {
            navigationItem.title = String.init(format: "Inbox (%lu unread)", (inboxMessages?.unreadMessagesCount)!);
        }
    }

    override func viewWillAppear(animated: Bool) {
        updateTitle();
        inboxMessages?.addDelegate(self);
    }

    override func viewDidDisappear(animated: Bool) {
        inboxMessages?.removeDelegate(self);
    }

    @IBAction func closeButtonPressed(sender: UIBarButtonItem) {
        inboxDelegate?.sampleInboxViewControllerDidFinished(self);
    }

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return Int((inboxMessages?.messagesCount)!);
    }

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        let message : R1InboxMessage = (inboxMessages?.messages[indexPath.row])! as! R1InboxMessage;

        return R1SampleInboxTableViewCell.heightForCell(message, cellWidth: tableView.frame.size.width)
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! R1SampleInboxTableViewCell;

        let message : R1InboxMessage = (inboxMessages?.messages[indexPath.row])! as! R1InboxMessage;

        cell.setInboxMessage(message);

        return cell
    }

    override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
        return true
    }

    override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
        if editingStyle == .Delete {
            let message : R1InboxMessage = (inboxMessages?.messages[indexPath.row])! as! R1InboxMessage;

            inboxMessages?.deleteMessage(message);
        }
    }

    // MARK: - Table view delegate

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let message : R1InboxMessage = (inboxMessages?.messages[indexPath.row])! as! R1InboxMessage;

        R1Inbox.sharedInstance().showMessage(message) { () -> Void in
            tableView.deselectRowAtIndexPath(indexPath, animated: true)
        }
    }

    // MARK: - R1InboxMessagesDelegate

    func inboxMessagesWillChanged() {
        tableView.beginUpdates()
    }

    func inboxMessagesDidChangeMessage(inboxMessage: R1InboxMessage!, atIndex index: UInt, forChangeType changeType: UInt, newIndex: UInt) {
        if (changeType == UInt(R1InboxMessagesChangeInsert)) {
            tableView.insertRowsAtIndexPaths([ NSIndexPath.init(forRow: Int(index), inSection: 0)], withRowAnimation: .Automatic);
        } else if (changeType == UInt(R1InboxMessagesChangeDelete)) {
            tableView.deleteRowsAtIndexPaths([ NSIndexPath.init(forRow: Int(index), inSection: 0)], withRowAnimation: .Automatic);
        } else if (changeType == UInt(R1InboxMessagesChangeUpdate)) {
            let cell = tableView.cellForRowAtIndexPath(NSIndexPath.init(forRow: Int(index), inSection: 0)) as! R1SampleInboxTableViewCell;
            let message : R1InboxMessage = (inboxMessages?.messages[Int(index)])! as! R1InboxMessage;

            cell.setInboxMessage(message);
        }
    }

    func inboxMessagesDidChanged() {
        tableView.endUpdates()
    }

    func inboxMessageUnreadCountChanged() {
        updateTitle()
    }
}

R1SampleInboxTableViewCell.swift

import UIKit

class R1SampleInboxTableViewCell: UITableViewCell {

    @IBOutlet weak var unreadMarkerView: UIView?
    @IBOutlet weak var alertLabel: UILabel?
    @IBOutlet weak var messageLabel: UILabel?
    @IBOutlet weak var dateLabel: UILabel?

    var dateFormatter: NSDateFormatter?

    func setInboxMessage(inboxMessage: R1InboxMessage) {
        unreadMarkerView?.hidden = !inboxMessage.unread;

        self.messageLabel?.text = inboxMessage.title;
        self.alertLabel?.text = inboxMessage.alert;
        self.dateLabel?.text = dateFormatter?.stringFromDate(inboxMessage.createdDate);
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        dateFormatter = NSDateFormatter?.init();
        dateFormatter?.dateStyle = .ShortStyle;
        dateFormatter?.timeStyle = .MediumStyle;
    }

    static func heightForCell(inboxMessage: R1InboxMessage, cellWidth: CGFloat) -> CGFloat {
        var height: CGFloat = 16+40;

        if (inboxMessage.alert != nil) {
            let paragraph : NSMutableParagraphStyle = NSMutableParagraphStyle.init();
            paragraph.lineBreakMode = .ByWordWrapping;

            height += inboxMessage.alert!._bridgeToObjectiveC().boundingRectWithSize(CGSize.init(width: cellWidth-16-15, height: 100), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName : UIFont.systemFontOfSize(14), NSParagraphStyleAttributeName: paragraph], context: nil).size.height;
        }

        return height;
    }
}

In Objective C example, initialize the R1SampleInboxViewController with the following method:

 [[R1SampleInboxViewController alloc] initInboxViewController]
Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.
Powered by Zendesk