Oracle Help Center | Oracle Responsys Mobile App Platform Cloud Service title

Message Center on iOS

Developing Message Center on iOS

This topic describes how to develop Message Center on iOS using the Oracle Responsys Mobile App Platform Cloud Service SDK. To understand how the SDK and Responsys support Message Center functionality, see the Message Center topic.

BEFORE YOU BEGIN:

Enabling Message Center

To enable Message Center in an iOS app, use the following methods:

[PushIOManager sharedInstance]setMessageCenterEnabled:YES]

[[PushIOManager sharedInstance] isMessageCenterEnabled];

NOTES:

Data retention policy

The duration Oracle caches Message Center messages is subject to change at anytime. Currently, messages are retained for 7 days from the fetched date, and then they are deleted. Apps should not rely on the SDK cache to act as storage for their app's Message Center messages. Apps must maintain their own storage and be developed to either retain messages for as long as messages are required, or delete messages when no longer needed. Each message has a unique message ID. Apps should check a message's ID to check whether or not the app has already retrieved and stored a message.

Fetching messages for Message Center

The Oracle Responsys Mobile App Cloud Platform SDK (Push SDK version 6.37.0 onwards) retrieves "Message Center" messages from Responsys at fixed intervals every time a mobile app is launched. The Push SDK stores retrieved messages locally, and they are served from the local storage on the device to your mobile app on demand.

Example - Fetching messages:

 [[PushIOManager sharedInstance] fetchMessagesForMessageCenter:@"Primary" CompletionHandler:^(NSError *error, NSArray *messages) {
        if (nil == error) {
            for (PIOMCMessage *mcMessage in messages) {
            NSLog(@"Message Subject: %@", mcMessage.subject);
        }
        }else{
            NSLog(@"Unable to fetch messages, reason: %@", error.description);
        }
    }];
        
PushIOManager.sharedInstance().fetchMessages(forMessageCenter: "Primary", completionHandler: {(error: Error?, messages: [Any]?) -> Void in
    if nil == error {
        //Load Messages
        let msgs = (messages as? [PIOMCMessage]) ?? []
        for msg in msgs {
            print(msg.debugDescription)
        }
    }
    else {
        print(error.debugDescription)
    }
})
        

Using PIOMCMessage

To import PIOMCMessage, add the following:

#import <PushIOManager/PIOMCMessage.h>
        
import PushIOManager
        

PIOMCMessage is a model class contains the following properties of messages:

Using the Error Codes

Different error types are returned to determine the different types of failures.

Example:

[[PushIOManager sharedInstance] fetchMessagesForMessageCenter:messageCenter CompletionHandler:^(NSError *error, NSArray *messages) {
    if (nil != error) {
        switch (error.code) {
            case PIOErrorCodeNoNetwork:
                NSLog(@"No network available to fetch messages Payload");
                break;
            case PIOErrorCodeMaximumRetryReached:
                NSLog(@"Maximum retrial reached to fetch messages");
                break;
            case PIOErrorCodeInvalidURL:
                NSLog(@"Invalid Message URL");
                break;
            case PIOErrorCodeInvalidPayload:
                NSLog(@"Invalid Message Payload");
                break;
            case PIOErrorCodeEmptyResponse:
                NSLog(@"Empty response received while fetching the messages");
                break;
            case PIOHTTTPStatusCodeInvalidAppOrAccountToken:
                NSLog(@"Provided AppToken or AccountToken is invalid. Error: %@", error.localizedDescription);
                break;
            case PIOHTTTPStatusCodeMCDisabled:
                NSLog(@"MessageCenter is disabled by server for provided message center name. Error: %@", error.localizedDescription);
                break;
            case PIOHTTTPStatusCodeMCFailure:
                NSLog(@"Failed to fetch messages for provided message center name. Error: %@", error.localizedDescription);
                break;
            default:
                NSLog(@"It requires investigation.");
                break;
        }
    }else{
        NSLog(@"Messages: %@", messages);
    }
}];
        
PushIOManager.sharedInstance().fetchMessages(forMessageCenter: self.msgCenter, completionHandler: {(error: Error?, messages: [Any]?) -> Void in
    if nil != error{
        let code = (error! as NSError).code
        switch code{
        case PIOErrorCode.noNetwork.rawValue:
            print("No network available to fetch messages Payload.");
        case PIOErrorCode.maximumRetryReached.rawValue:
            print("Maximum retrial reached to fetch messages.");
        case PIOErrorCode.invalidURL.rawValue:
            print("Invalid Message URL.");
        case PIOErrorCode.invalidPayload.rawValue:
            print("Invalid Message Payload.")
        case PIOErrorCode.emptyResponse.rawValue:
            print("Empty response received while fetching the messages.");
        case Int(PIOHTTTPStatusCodeInvalidAppOrAccountToken):
            print("Provided AppToken or AccountToken is invalid.")
        case Int(PIOHTTTPStatusCodeMCDisabled):
            print("Messages are disabled by server for provided message center name.");
        case Int(PIOHTTTPStatusCodeMCFailure):
            print("Failed to fetch messages for provided message center name.");
        default:
            print("It requires investigation.")
        }
    }else{
        print("Messages: \(messages)")
    }
        

Fetching Rich Push content for the individual message

Your mobile app needs to fetch the rich content for the individual Rich Push message. Rich content is served only once for a message, therefore apps must store the rich content upon retrieval. Use fetchRichContent as follows:

NOTES:

[[PushIOManager sharedInstance] fetchRichContentForMessage:self.message.messageID CompletionHandler:^(NSError *error, NSString *messageID, NSString *content) {
    NSLog(@"MessageID: %@ RichContent: %@ Error: %@", messageID, content, error);
}];
        
PushIOManager.sharedInstance().fetchRichContent(forMessage: "messageID") { (error, messageID, content) in
    print("MessageID: \(messageID) RichContent: \(content) Error: \(error)")
}
        

Capturing Raw Response in Application

NOTE: The SDK makes the server request to fetch messages for all inboxes internally. So listening for the raw response in application may not provide business value for the application. Be careful if application needs to use the received raw response.

If desired, your mobile application can capture the raw messages (JSON) response received from Responsys:

[1.] Put an observer for notification constant PIOMCRawResponseCaptureNotification

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(printMCLog:) name:PIOMCRawResponseCaptureNotification object:nil];
        
NotificationCenter.default.addObserver(self, selector: #selector(self.printMCLog), name:NSNotification.Name.PIOMCRawResponseCapture, object: nil)
        

[2.] Fetch the message response from notification's userinfo (key PIOMCRawResponseValue) and convert it into a string to use:

-(void)printMCLog:(NSNotification *)notification{
    NSData *responseData = notification.userInfo[PIOMCRawResponseValue];
    NSString *response = [[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding];
    NSLog(@"Inbox Response %@", response);
}
        
func printMCLog(notification:Notification){
    if let data = notification.object as? Data {
        let response = String.init(data: data, encoding: String.Encoding.utf8)
        print("Inbox Response: \(response)")
    }
}
        

App Icon Badges

The Responsys SDK update for 19B includes additional features to support badge count for messages in the message center. Badging is enabled by default in the SDK. It is the responsibility of the app developer to reset the app's badge count on certain actions if required by the app.

Prerequisites:

The Responsys iOS SDK provides the following APIs to manage this functionality from the app.

[1] Set badge count from app

Typically the badge count is set by the server. But in certain cases, the badge count needs to be set explicitly. Use setBadgeCount API to set the badge count of app which will also sync this badge count value with the Responsys server. If an error occurs while syncing the badge count to the Responsys platform server, an error will be returned in the completion handler and the badge count will not be set.

NOTE: When setting the badge count, the value cannot be less than 0. The badge count value of 0 clears the badge icon for the app.

[[PushIOManager sharedInstance] setBadgeCount:2 completionHandler:^(NSError *error, NSString *response) {
    if (nil == error) {
        // Badge count set and synced successfully.
    } else {
        // Error occurred, unable to sync and set badge count
        // Handle error. If required you can set app badge count locally by calling iOS API [[UIApplication sharedApplication] setApplicationIconBadgeNumber:2]; 
        NSLog(@"Unable to set badge count, reason: %@", error.description);
    }
}];
        
PushIOManager.sharedInstance().setBadgeCount(2, completionHandler: { (error, response) in
    if let error = error {
        // Error occurred, unable to sync and set badge count
        // Handle error. If required you can set app badge count locally by calling iOS API UIApplication.shared.applicationIconBadgeNumber = 2
        print(error.debugDescription)
    } else {
        // Badge count set and synced successfully.
    }
})
        

[2] Reset the badge count

Use this API to reset and clear the badge count from the app icon. This API syncs the badge count value 0 with the server. If an error occurs while syncing the badge count to the Responsys platform server, an error will be returned in the completion handler and the app badge count will not be cleared.

NOTE: Using this API or setting the badge count to 0 will also clear the App notifications from the notification center.

[[PushIOManager sharedInstance] resetBadgeCountWithCompletionHandler:^(NSError *error, NSString *response) {
    if (nil == error) {
        // Badge count set and synced successfully.
    } else {
        // Error occurred, unable to sync and set badge count
        // Handle error. If required you can set app badge count locally by calling iOS app [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; 
        NSLog(@"Unable to reset the badge count, reason: %@", error.description);
    }
}];
        
PushIOManager.sharedInstance().resetBadgeCount(completionHandler: { (error, response) in
    if let error = error {
        // Error occurred, unable to sync and set badge count
        // Handle error. If required you can set app badge count locally by calling iOS app UIApplication.shared.applicationIconBadgeNumber = 0
    } else {
        // Badge count set and synced successfully.
    }
})
        

[3] Get the badge count for the App

This API will return the current value of the app badge count.

int badgeCount = [[PushIOManager sharedInstance] getBadgeCount];
        
let badgeCount: Int = PushIOManager.sharedInstance().getBadgeCount()