Flows and Views

Learn about the OWUIFlows and OWUIViews protocols that provide two approaches to add the Conversation module and general UI to your iOS app.

The OWUIFlows and OWUIViews protocols provide two approaches to add the Conversation module and the general UI to your app: Flows and Views.

Either approach enables you to incorporate elements, such as PreConversation, Conversation, and Comment Creation experiences.

Conversation below video

Conversation below video

public protocol OWUIFlows {
    func preConversation(postId: OWPostId,
                         article: OWArticleProtocol,
                         presentationalMode: OWPresentationalMode,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWFlowActionsCallbacks?,
                         completion: @escaping OWViewCompletion)

    func conversation(postId: OWPostId,
                      article: OWArticleProtocol,
                      presentationalMode: OWPresentationalMode,
                      additionalSettings: OWAdditionalSettingsProtocol,
                      callbacks: OWFlowActionsCallbacks?,
                      completion: @escaping OWDefaultCompletion)

    func commentCreation(postId: OWPostId,
                         article: OWArticleProtocol,
                         presentationalMode: OWPresentationalMode,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWFlowActionsCallbacks?,
                         completion: @escaping OWDefaultCompletion)

    func commentThread(postId: OWPostId,
                       article: OWArticleProtocol,
                       commentId: OWCommentId,
                       presentationalMode: OWPresentationalMode,
                       additionalSettings: OWAdditionalSettingsProtocol,
                       callbacks: OWFlowActionsCallbacks?,
                       completion: @escaping OWDefaultCompletion)
}
public protocol OWUIFlows {
    @MainActor
    func preConversation(postId: OWPostId,
                         article: OWArticleProtocol,
                         presentationalMode: OWPresentationalMode,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWFlowActionsCallbacks?) async throws -> UIView

    @MainActor
    func conversation(postId: OWPostId,
                      article: OWArticleProtocol,
                      presentationalMode: OWPresentationalMode,
                      additionalSettings: OWAdditionalSettingsProtocol,
                      callbacks: OWFlowActionsCallbacks?) async throws

    @MainActor
    func commentCreation(postId: OWPostId,
                         article: OWArticleProtocol,
                         presentationalMode: OWPresentationalMode,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWFlowActionsCallbacks?) async throws

    @MainActor
    func commentThread(postId: OWPostId,
                       article: OWArticleProtocol,
                       commentId: OWCommentId,
                       presentationalMode: OWPresentationalMode,
                       additionalSettings: OWAdditionalSettingsProtocol,
                       callbacks: OWFlowActionsCallbacks?) async throws
}
public protocol OWUIViews {
    func preConversation(postId: OWPostId,
                         article: OWArticleProtocol,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWViewActionsCallbacks?,
                         completion: @escaping OWViewCompletion)

    func conversation(postId: OWPostId,
                      article: OWArticleProtocol,
                      additionalSettings: OWAdditionalSettingsProtocol,
                      callbacks: OWViewActionsCallbacks?,
                      completion: @escaping OWViewCompletion)

    func commentCreation(postId: OWPostId,
                         article: OWArticleProtocol,
                         commentCreationType: OWCommentCreationType,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWViewActionsCallbacks?,
                         completion: @escaping OWViewCompletion)

    func commentThread(postId: OWPostId,
                       article: OWArticleProtocol,
                       commentId: OWCommentId,
                       additionalSettings: OWAdditionalSettingsProtocol,
                       callbacks: OWViewActionsCallbacks?,
                       completion: @escaping OWViewCompletion)

    func reportReason(postId: OWPostId,
                      commentId: OWCommentId,
                      parentId: OWCommentId,
                      additionalSettings: OWAdditionalSettingsProtocol,
                      callbacks: OWViewActionsCallbacks?,
                      completion: @escaping OWViewCompletion)
}
public protocol OWUIViews {
    @MainActor
    func preConversation(postId: OWPostId,
                         article: OWArticleProtocol,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWViewActionsCallbacks?) async throws -> UIView

    @MainActor
    func conversation(postId: OWPostId,
                      article: OWArticleProtocol,
                      additionalSettings: OWAdditionalSettingsProtocol,
                      callbacks: OWViewActionsCallbacks?) async throws -> UIView

    @MainActor
    func commentCreation(postId: OWPostId,
                         article: OWArticleProtocol,
                         commentCreationType: OWCommentCreationType,
                         additionalSettings: OWAdditionalSettingsProtocol,
                         callbacks: OWViewActionsCallbacks?) async throws -> UIView

    @MainActor
    func commentThread(postId: OWPostId,
                       article: OWArticleProtocol,
                       commentId: OWCommentId,
                       additionalSettings: OWAdditionalSettingsProtocol,
                       callbacks: OWViewActionsCallbacks?) async throws -> UIView

    @MainActor
    func reportReason(postId: OWPostId,
                      commentId: OWCommentId,
                      parentId: OWCommentId,
                      additionalSettings: OWAdditionalSettingsProtocol,
                      callbacks: OWViewActionsCallbacks?) async throws -> UIView
}

Each implementation approach is explained in the Approaches section.


Approaches

Flows

This approach relies upon OpenWeb's default UI.

When implementing a Conversation with the Flows approach, you should configure one of the three flows in the following table.

ViewDescription
PreConversationShow a preview of comments at the end of an article to encourage engagement with a Conversation. This is an entry point to the full-page Conversation experience.
ConversationShow a full-page Conversation experience that initiates when the user triggers a call-to-action (CTA) button
Comment CreationNavigate directly to a page in which the end user can create a new comment
Comment ThreadShow a comment thread, starting from the root comment (commentId)

Flow Recipes

Use the following recipes to configure one of the flows.

iOS SDK PreConversation Flow

Use async-await

Use completion handler

iOS SDK Conversation Flow

Use async-await

Use completion handler

iOS SDK Comment Creation Flow

Use async-await

Use completion handler

iOS SDK Comment Thread Flow

Use async-await

Use completion handler

Views

Implementing a Conversation module with the Views approach, gives you the ability to control the behavior between views.

In this workflow, the following occurs:

  1. A user takes an action, such as tapping a button.
  2. The user's action triggers OpenWeb's callbacks API to return a callback, signifying an event occurred.
  3. As the developer, you use this event to make another API call to OpenWeb.
  4. OpenWeb's API responds with the specific view element related to the API call.
  5. As the developer, you manage the presentation of the views or elements returned by OpenWeb. You can decide whether these views or elements are displayed or hidden from the user.

The following table lists the configurable views that are returned.

ViewDescription
PreConversationA preview of comments at the end of an article to encourage engagement with a Conversation
ConversationThe main view for the Conversation
Comment CreationA view for entering a comment
Comment ThreadShow a comment thread, starting from the root comment (commentId)
Report ReasonScreen listing possible report options. Use the OWViewActionsCallbacks to signal when to display these report options.

View Recipes

Use the following recipes to configure one of the views.

iOS SDK PreConversation View

Use async-await

Use completion handler

iOS SDK Conversation View

Use async-await

Use completion handler

iOS SDK Comment Creation View

Use async-await

Use completion handler

iOS SDK Comment Thread View

Use async-await

Use a callback

iOS SDK Report Reason View

Use async-await

Use a callback


Methods

The following sections explain the methods available for flows and views.

commentCreation()

Starts the flow or retrieves the view for comment creation

var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve flows layer
let flows: OWUIFlows = manager.ui.flows

flows.commentCreation(
  postId: "somePostId",
  article: article,
  presentationalMode: OWModelPresentationStyle,
  additionalSettings: commentCreationSettings,
  completion: commentClosure
)
var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve views layer
let views: OWUIViews = manager.ui.views

views.commentCreation(
  postId: "somePostId",
  additionalSettings: additionalSettings,
  callbacks: OWViewActionsCallbacks,
  completion: commentCreationViewClosure
)

commentThread()

Starts the flow or retrieves the view for comment thread

var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve flows layer
let flows: OWUIFlows = manager.ui.flows

flows.commentThread(
    postId: "somePostId", 
    article: article,
    commentId: "someCommentId",
    presentationalMode: .push(navigationController: navController),
    additionalSettings: additionalSettings,
    callbacks: nil,
    completion: commentThreadClosure
)
var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve views layer
let views: OWUIViews = manager.ui.views

views.commentCreation(
    postId: "somePostId",
    article: article
    commentId: "someCommentId"
    additionalSettings: additionalSettings,
    callbacks: OWViewActionsCallbacks,
    completion: commentCreationViewClosure
)

conversation()

Starts the flow or retrieves the view for the conversation

var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve flows layer
let flows: OWUIFlows = manager.ui.flows

flows.conversation(
  postId: "somePostId",
  article: article,
  presentationalMode: OWModelPresentationStyle,
  additionalSettings: conversationSettings,
  completion: conversationClosure
)
var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve views layer
let views: OWUIViews = manager.ui.views

views.conversation(
  postId: "somePostId", 
  article: article,
  additionalSettings: additionalSettings,
  callbacks: OWViewActionsCallbacks,
  completion: conversationViewClosure
)

preConversation()

Starts the flow or retrieves the view for the pre-conversation

var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve flows layer
let flows: OWUIFlows = manager.ui.flows

flows.preConversation(
  postId: "somePostId",
  article: article,
  presentationalMode: OWModelPresentationStyle,
  additionalSettings: preConversationSettings,
  completion: preConversationClosure
)
var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve views layer
let views: OWUIViews = manager.ui.views

views.preConversation(
  postId: "somePostId", 
  article: article,
  additionalSettings: additionalSettings,
  callbacks: OWViewActionsCallbacks,
  completion: preConversationViewClosure
)

reportReason()

Retrieves the view for the report reason

var manager: OWManagerProtocol = OpenWeb.manager

// Retrieve views layer
let views: OWUIViews = manager.ui.views

views.reportReason(
  postId: "targetPostId",
  commentId: "targetCommentId",
  parentId: "parentCommentId",
  additionalSettings: additionalSettings,
  callbacks: reportActionsCallbacks,
  completion: reportViewClosure
)
PropertyDescription
additionalSettings OWAdditionalSettingsProtocolDefines the settings of each component in a flow/view. Possible Values: commentCreationSettings, conversationSettings, preConversationSettings. See: OWAdditionalSettings
article OWArticleInformation about the article associated with the flow. See: Article
callbacks OWViewActionsCallbacksHandles the response to a user action after the action has occurred. See OWViewActionsCallbacks
commentId stringUnique identifier of a comment
completion functionClosure that handles the completion of the flow, success scenarios, and failure scenarios. The closure logic is defined in the relevant recipe. Possible Values: commentClosure, conversationClosure, preConversationClosure
parentId stringUnique identifier of the parent comment
postId stringUnique article identifier that is specific to the article page. The ideal postId has the following characteristics: Aligns with the URL slug (an-article-title) or article ID (14325), Is less than 50 characters ideally 15 characters, Uses a combination of letters number dashes (-) or hyphens (_), Except for the regex [^\w\s-:.$~] does not include special characters
presentationalModePossible Values: .present(viewController: UIViewController, style: OWModalPresentationStyle), .push(navigationController: UINavigationController). See: OWModelPresentationStyle

Enumerations and Structs

OWAdditionalSettings

public protocol OWAdditionalSettingsProtocol {

    var preConversationSettings: OWPreConversationSettingsProtocol { get }

    var fullConversationSettings: OWConversationSettingsProtocol { get }

    var commentCreationSettings: OWCommentCreationSettingsProtocol { get }

    var commentThreadSettings: OWCommentThreadSettingsProtocol { get }

}
SettingsDescription
commentCreationSettings OWCommentCreationSettingsProtocolSets the initial comment creation flow settings. Possible Values: .regular (default), .floatingKeyboard, .light
fullConversationSettings OWConversationSettingsProtocolSets the initial Conversation flow settings. style: .regular (default), .compact, .custom(communityGuidelinesStyle: OWCommunityGuidelinesStyle, communityQuestionsStyle: OWCommunityQuestionsStyle, spacing: OWConversationSpacing). allowPullToRefresh: true (default), false to disable the pull-to-refresh gesture
preConversationSettings OWPreConversationSettingsProtocolSets the initial preConversation flow settings. style: .regular (default) Conversation headers and top comments, .compact Preview of one comment, .ctaButtonOnly A button with the number of comments in the conversation, .ctaWithSummary Conversation headers and a button to show the full conversation, .custom Custom number of comments (up to 8), headers, and spacing.
commentThreadSettings OWCommentThreadSettingsProtocolSets the initial Conversation flow settings. performActionType: .none (default), .changeRank(from:, to:), .reply, .report. allowPullToRefresh: true (default), false to disable the pull-to-refresh gesture

OWCommunityGuidelinesStyle

SettingDescription
OWCommunityGuidelinesStyle OWCommunityGuidelinesStyleManner in which the screen is displayed. Possible Values: .none, .compact, .regular

OWCommunityQuestionsStyle

SettingDescription
OWCommunityQuestionsStyle OWCommunityQuestionsStyleManner in which the screen is displayed. Possible Values: .compact, .regular

OWConversationRoute

Setting

Description

OWConversationRoute

Flow to open the conversation with.
Possible Values:

  • .none (default)
  • .commentCreation(type: OWCommentCreationType)
  • .commentThread(commentId: OWCommentId)

OWConversationSpacing

Setting

Description

OWConversationSpacing OWConversationSpacing

Manner in which the screen is displayed.
Possible Values:

  • .regular (default)
  • .compact
  • .custom(betweenComments: CGFloat, communityGuidelines: CGFloat, communityQuestions: CGFloat)

The CGFloat values must be between 5.0 - 40.0.

OWError

SettingDescription
OWError stringError returned

OWFlowActionsCallbacks

typealias OWFlowActionsCallbacks = (
  OWFlowActionCallbackType, 
  OWViewSourceType, 
  String) 
-> Void
SettingsDescription
OWFlowActionsCallbackType stringUser action performed or error that occurred. See OWFlowActionCallbackType
OWViewSourceType stringView from which information is received. See OWViewSourceType

OWFlowActionCallbackType

SettingsDescription
OWFlowActionCallbackType stringUser action performed. Possible Values: .conversationDismissed, .openPublisherProfile(ssoPublisherId: String, type: OWUserProfileType, presentationalMode: OWPresentationalMode)

OWModalPresentationStyle

Setting

Description

OWModalPresentationStyle string

Manner in which the screen is displayed.
Possible Values:

.fullscreen,
.pageSheet

OWPresentationalMode

Setting

Description

OWPresentationalMode string

Manner in which the OpenWeb view is presented or pushed.
Possible Values:

  • .present(viewController: UIViewController, style: OWModalPresentationStyle)
  • .push(navigationController: UINavigationController)

OWViewActionsCallbacks

typealias OWViewActionsCallbacks = (
  OWViewActionCallbackType, 
  OWViewSourceType, 
  String
) -> Void
SettingsDescription
OWViewActionCallbackTypeUser action performed or error that occurred. See OWViewActionCallbackType
OWViewSourceTypeView from which information is received. See OWViewSourceType

OWViewActionCallbackType

Settings

Description

OWViewActionCallbackType string

User action performed or error that occurred.
Possible Values:

  • .adClosed
  • .articleHeaderPressed
  • .closeConversationPressed
  • .closeReportReason
  • .communityGuidelinesPressed(url: URL)
  • .communityQuestionsPressed
  • .contentPressed
  • .error(_ error: OWError)
  • .openPublisherProfile(userId: String)
  • .openReportReason(commentId: OWCommentId, parentId: OWCommentId)
  • .postCommentPressed
  • .showMoreCommentsPressed
  • .writeCommentPressed

OWViewControllerCompletion

typealias OWViewControllerCompletion = (
  Result<UIViewController, 
  OWError>
) -> Void

OWViewCompletion

typealias OWViewCompletion = (
  Result<UIView, 
  OWError>
) -> Void

OWViewSourceType

Settings

Description

OWViewSourceType string

View from which information is received.
Possible Values:

  • .commentCreation
  • .conversation
  • .preConversation