Skip to content

Tutorials

Ryan Matthew Pierson edited this page Jun 22, 2020 · 2 revisions

This guide provides tutorials for working with the Community iOS SDK API providers and utility methods.

Intro to the Client classes

When you work with our API providers and utility methods to interact with Khoros Community entities like users, messages, kudos, and images, you’ll generally be working with the same set of classes. We’ll give you a quick introduction to them here, as you’ll be seeing these throughout our tutorials.

  • LiClient enumerates our API providers. It also contains the properties of the API providers and is used to generate the URLRequest.
  • LiClientManager contains the request method you'll be using to perform actions like posting a message, giving a kudo, adding an image, or creating a user using the providers listed in LiClient.
  • LiClientRequestParams is a class that includes all of the request parameter builders used by our API providers. See Community iOS SDK API reference for details.

Handling a 401 authentication error

If an anonymous user does not have permission to perform a certain action, such as replying to a message or giving kudos, the SDK returns a 401 (Unauthorized) error. The following example shows how to check for the 401 error and display the error in the UI.

let requestParams = try! LiMessagesByBoardIdClientRequestParams(boardId: selectedBoard)
LiSDKManager.shared().clientManager.request(client: .liMessagesByBoardIdClient(requestParams: requestParams), completionHandler: { (result: Result<[LiMessage]>) in
    switch result {
    case .success(let data):
        //Show result
    case .failure(let error):
        //Check for 401 error
        if err.httpCode == LiCoreSDKConstants.LiErrorCodes.httpCodeUnauthorized {
            //Show user not logged in
        }
        //Check of other errors
    }
})

Then you can use the following to begin the login flow for the anonymous user:

LiSDKManager.shared().liAuthManager.initLoginFlow(from: self, deviceToken: deviceToken, notificationProvider: notificationProvider)

Working with messages

This section provides a walkthrough of actions used when working with messages.

Post a topic message

Let’s look at an example class that posts a new topic message to the community. We’ll build a client using the API provider LiClient.liCreateMessageClient(requestParams: LiCreateMessageClientRequestParams). Note that this example creates a new topic. Creating a reply takes other considerations. We show an example of creating a reply later on.

We need to:

  • Build the request parameters for the client
  • Create the client
  • Call the client

All of our clients take a set of request parameters, so the first thing we do is build those parameters to pass to the client. Client request parameters are built using LiClientRequestParams. There is a specific builder for each client. To post a new message, we need the subject and body text, the board where the message will be posted, and (optionally) an image ID and title if the user has uploaded an image.

var requestParams: LiCreateMessageClientRequestParams
do {
    requestParams = try LiCreateMessageClientRequestParams(subject: topic, body: body, boardId: boardId, imageId: nil, imageName: nil)
} catch LiError.invalidArgument(let errorMessage) {
    //Handle errors related to invalid parameters
}
LiSDKManager.shared().clientManager.request(client: .liCreateMessageClient(requestParams: requestParams), completionHandler: { (result: Result<[LiMessage]>) in
    switch result {
    case .success(_):
        //Update UI
    case .failure(let error):
        if let err = error as? LiBaseError {
            //handle error
        } else {
            //handle error
        }
    }
})

Post a topic message with an image

Posting a topic with an image adds another layer to our topic post example. The flow requires that we upload the image to the community first. This returns an image ID. The provider uses the ID to create a macro string and appends that string to the end of the message body entered by the user.

You’ll upload the image to the community using liUploadImageClient, and you’ll build the request parameters with LiUploadImageClientRequestParams.

//Create LiUploadImageClientRequestParams parameters
var requestParams: LiUploadImageClientRequestParams
do {
    requestParams = try LiUploadImageClientRequestParams(title: topic, description: description, imageName: imageName, image: image)
    //Upload image
    LiSDKManager.shared().clientManager.request(client: .liUploadImageClient(requestParams: requestParams), completionHandler: { (result: Result<[LiImageResponse]>) in
        switch result {
        case success(let data):
            //Get image id.
            imageId = data.id
            //Send message with the image id and the image name.
            createMessage(subject: topic, body: body, boardId: boardId, imageId: imageId, imageName: imageName)
        case failure(let error):
            // handle error
        }
    })
} catch LiError.invalidArgument(let errorMessage) {
    //Handle errors related to invalid parameters
}
 
func createMessage( subject: String, body: String, boardId: String, imageId: String, imageName: String ) {
    do {
        let requestParams: LiCreateMessageClientRequestParams = try LiCreateMessageClientRequestParams(subject: topic, body: body, boardId: boardId, imageId: imageId, imageName: imageName)
        LiSDKManager.shared().clientManager.request(client: .liCreateMessageClient(requestParams: requestParams), completionHandler: { (result: Result<[LiMessage]>) in
            switch result {
            case .success(_):
                //Update UI
            case .failure(let error):
                if let err = error as? LiBaseError {
                    //handle error
                } else {
                    //handle error
                }
            }
        })
    } catch LiError.invalidArgument(let errorMessage) {
        //Handle errors related to invalid parameters
    }
}

Get a message

To retrieve a specific message, you’ll use the LiClient.liMessageClient(requestParams: LiMessageClientRequestParams) provider. Here’s an example.

The provider returns the LiMessage object on the first index of the response array.

do {
    let requestParams: LiMessageClientRequestParams = try LiMessageClientRequestParams(messageId: messageId)
    LiSDKManager.shared().clientManager.request(client: .liMessageClient(requestParams: requestParams), completionHandler: { (result: Result<[LiMessage]>) in
        switch result {
        case .success(let data):
            let message = data.first
        case .failure(let error):
            if let err = error as? LiBaseError {
                //handle error
            } else {
                //handle error
            }
        }
    })
} catch LiError.invalidArgument(let errorMessage) {
    //Handle errors related to invalid parameters
}

Post a reply

Before we can post a reply, we want to get and display the parent message. We showed an example of how to get the message earlier. While replies and topic messages are both stored as messages in the database, we create a reply using a different provider than when creating a topic.

To create a reply, we use LiClient.liCreateReplyClient(requestParams: LiCreateReplyClientRequestParams). We’re passing the body text of the reply and the parent message ID to liCreateReplyClient, as well as in image ID and name if the user uploads an image.

do {
    let requestParams: LiCreateReplyClientRequestParams = try LiCreateReplyClientRequestParams(body: body, messageId: messageId, imageId: nil, imageName: nil)
    LiSDKManager.shared().clientManager.request(client: .liCreateReplyClient(requestParams: requestParams), completionHandler: { (result: Result<[LiMessage]>) in
        switch result {
        case .success(let data):
            //Update UI
        case .failure(let error):
            if let err = error as? LiBaseError {
                //handle error
            } else {
                //handle error
            }
        }
    })
} catch LiError.invalidArgument(let errorMessage) {
    //Handle errors related to invalid parameters
}