Add a conversation to your app

The Viafoura SDK ships both UIKit view controllers and SwiftUI views. Follow the section that matches how your screen is built.

Using UIKit

Implementation

  1. Implement theVFLoginDelegate. This delegate will be called when the user tries to interact with the container in a way that needs authentication. For example: Liking a comment or trying to create their own comment.
    Your app should present your authentication flow and authenticate with Viafoura SDK Authenticate your users
extension ArticleViewController: VFLoginDelegate {
    func startLogin() {
      	// Launch your custom login/signup flow
    }
}
  1. Create yourVFArticleMetadata object.
let articleMetadata = VFArticleMetadata(
  url: "https://demo.viafoura.com/posts/so-you-got-new-engagement-tools-now-what",
  title: "So you got New Engagement Tools, Now What?",
  subtitle: "What better way to grow a community than with on-site engagement tools?",
  thumbnailUrl: "https://www.datocms-assets.com/55856/1636662761-impact-engagement.jpg?fit=crop&fm=webp&h=428&w=856")
ValueTypeDescription
urlURL StringURL of the content
titleStringTitle of the content
subtitleStringSubtitle of the content
thumbnailUrlURL StringContent thumbnail URL
  1. Create yourVFSettings object.
    For customization options, refer to Use custom colors and fonts
let colors = VFColors(colorPrimary: .green, colorPrimaryLight: .systemGreen)
let settings = VFSettings(colors: colors)
  1. Create the conversation view controller.
let callbacks: VFActionsCallbacks = { type in
    switch type {
    case .writeNewCommentPressed(let actionType):
        let newCommentViewController = VFNewCommentViewController.new(
            newCommentActionType: actionType,
            containerId: containerId,
            articleMetadata: articleMetadata,
            loginDelegate: self,
            settings: settings
        )
        self.present(newCommentViewController, animated: true)
    case .openProfilePressed(let userUUID, let presentationType):
        let profileViewController = VFProfileViewController.new(
            userUUID: userUUID,
            presentationType: presentationType,
            loginDelegate: self,
            settings: settings
        )
        self.present(profileViewController, animated: true)
        break
    }
} 

let preCommentsViewController = VFPreviewCommentsViewController.new(
  containerId: containerId, 
  articleMetadata: articleMetadata, 
  loginDelegate: self, 
  settings: settings
)
preCommentsViewController.setActionCallbacks(callbacks: callbacks)
  1. Add the conversation view to your view controller. Make sure you have created a container view to add the conversation VC into.
addChild(preCommentsViewController)

youCommentsContainerView.addSubview(preCommentsViewController.view)

preCommentsViewController.view.frame = CGRect(x: 0, y: 0, width: yourCommentsContainerView.frame.width, height: preCommentsViewController.view.frame.height)   
preCommentsViewController.willMove(toParent: self)
preCommentsViewController.didMove(toParent: self)

Implement the VFLayoutDelegate

The view controller content height will change depending on the amount of content present on the container. Listen to height changes by implementing the VFLayoutDelegate and update the container view height accordingly.

extension ArticleViewController: VFLayoutDelegate {
    func containerHeightUpdated(viewController: VFUIViewController, height: CGFloat) {
        self.yourCommentsContainerViewHeight.constant = height
    }
}

Choose a profile style

VFProfileViewController ships two layouts. Pass style to new to pick one; omitting it keeps the default.

case .openProfilePressed(let userUUID, let presentationType):
    let profileViewController = VFProfileViewController.new(
        userUUID: userUUID,
        presentationType: presentationType,
        loginDelegate: self,
        settings: settings,
        style: .unity
    )
    self.present(profileViewController, animated: true)
ValueDescription
.legacyThe full-screen profile with Feed, Profile and Community segments. Used when style is omitted.
.unityThe profile tray that matches the Viafoura web experience. A menu switches between Notifications, Community and Profile, other users open on their own member screen, and the logged-in user can edit their profile in place.

To open the drawer on a specific Community list, pass communityTab. It is ignored by .default.

let profileViewController = VFProfileViewController.new(
    userUUID: userUUID,
    presentationType: .community,
    loginDelegate: self,
    settings: settings,
    style: .unity,
    communityTab: .followers
)
ValueDescription
.followingUsers the logged-in user follows
.followersUsers following the logged-in user
.mutedUsers the logged-in user muted

Both styles dismiss themselves when the user taps Close, or pop when pushed onto a navigation controller, and send closeProfilePressed through the action callbacks.

Using SwiftUI

The SDK provides VFPreviewCommentsView, VFNewCommentView and VFProfileView as native SwiftUI views (iOS 13+). They wrap the UIKit view controllers above, so you don't need to implement VFLoginDelegate or VFLayoutDelegate yourself: login and height updates are exposed as closures and the view sizes itself.

Implementation

  1. Create yourVFArticleMetadata and VFSettings objects. These are the same objects used by UIKit. See the tables and customization links in the UIKit section above.
let articleMetadata = VFArticleMetadata(
  url: "https://demo.viafoura.com/posts/so-you-got-new-engagement-tools-now-what",
  title: "So you got New Engagement Tools, Now What?",
  subtitle: "What better way to grow a community than with on-site engagement tools?",
  thumbnailUrl: "https://www.datocms-assets.com/55856/1636662761-impact-engagement.jpg?fit=crop&fm=webp&h=428&w=856")

let colors = VFColors(colorPrimary: .green, colorPrimaryLight: .systemGreen)
let settings = VFSettings(colors: colors)
  1. Add VFPreviewCommentsView to your view. Pass onLogin to present your authentication flow and onAction to handle user actions. Drop the view anywhere in a ScrollView or VStack; it reports its own height, so no container view or layout delegate is required.
struct ArticleView: View {
    let containerId: String
    let articleMetadata: VFArticleMetadata
    let settings: VFSettings

    @State private var showLogin = false
    @State private var newCommentItem: NewCommentItem?
    @State private var profileTarget: ProfileTarget?

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 0) {
                // Your article content

                VFPreviewCommentsView(
                    containerId: containerId,
                    articleMetadata: articleMetadata,
                    settings: settings,
                    onLogin: { showLogin = true },
                    onAction: handleAction
                )
                .padding(.top, 24)
            }
        }
        .sheet(isPresented: $showLogin) {
            // Launch your custom login/signup flow
        }
        .sheet(item: $newCommentItem) { item in
            VFNewCommentView(
                actionType: item.action,
                containerId: containerId,
                articleMetadata: articleMetadata,
                settings: settings,
                onLogin: { showLogin = true }
            )
        }
        .sheet(item: $profileTarget) { target in
            VFProfileView(
                userUUID: target.userUUID,
                presentationType: target.presentationType,
                settings: settings,
                onLogin: { showLogin = true }
            )
        }
    }
}
ParameterTypeDescription
onLogin() -> VoidCalled when the user tries to interact with the container in a way that needs authentication. Present your login flow and authenticate with the SDK Authenticate your users
onActionVFActionsCallbacksCalled when the user taps an action such as writing a comment or opening a profile. Same callback type as setActionCallbacks in UIKit.
themeVFTheme?Optional. Defaults to following the SwiftUI colorScheme, so dark mode is handled automatically.
autoSizeBoolOptional, defaults to true. The view sets its own frame height as the content changes. Set to false to control the height yourself.
onHeightChange(CGFloat) -> VoidOptional. Called with the new content height, equivalent to VFLayoutDelegate in UIKit. Only needed when autoSize is false.
  1. Handle the action callbacks. Store the action in state and present the matching SDK view in a sheet, as shown in step 2.
extension ArticleView {
    func handleAction(_ type: VFActionCallbackType) {
        switch type {
        case .writeNewCommentPressed(let actionType):
            newCommentItem = NewCommentItem(action: actionType)
        case .openProfilePressed(let userUUID, let presentationType):
            profileTarget = ProfileTarget(userUUID: userUUID, presentationType: presentationType)
        default:
            break
        }
    }

    struct NewCommentItem: Identifiable {
        let id = UUID()
        let action: VFNewCommentActionType
    }

    struct ProfileTarget: Identifiable {
        let id = UUID()
        let userUUID: UUID
        let presentationType: VFProfilePresentationType
    }
}

Choose a profile style

VFProfileView takes the same style parameter as VFProfileViewController. It defaults to .legacy; pass .unity for the profile tray. See the UIKit section above for what each style shows.

.sheet(item: $profileTarget) { target in
    VFProfileView(
        userUUID: target.userUUID,
        presentationType: target.presentationType,
        settings: settings,
        style: .unity,
        onLogin: { showLogin = true }
    )
}

Fetch the comment count for a container (optional)

Implement the commentCount call passing the container ID. This works the same way for UIKit and SwiftUI.

let vfLiveCommentsService = ViafouraSDK.comments()
vfLiveCommentsService.commentCount(containerId: "123123", completion: { [weak self] result in
    switch result {
      case .success(let count):
        break
      case .failure(let error):
        break
    }
})

Did this page help you?