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
- Implement the
VFLoginDelegate. 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
}
}- Create your
VFArticleMetadataobject.
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")| Value | Type | Description |
|---|---|---|
url | URL String | URL of the content |
title | String | Title of the content |
subtitle | String | Subtitle of the content |
thumbnailUrl | URL String | Content thumbnail URL |
- Create your
VFSettingsobject.
For customization options, refer to Use custom colors and fonts
let colors = VFColors(colorPrimary: .green, colorPrimaryLight: .systemGreen)
let settings = VFSettings(colors: colors)- 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)- 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)| Value | Description |
|---|---|
.legacy | The full-screen profile with Feed, Profile and Community segments. Used when style is omitted. |
.unity | The 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
)| Value | Description |
|---|---|
.following | Users the logged-in user follows |
.followers | Users following the logged-in user |
.muted | Users 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
- Create your
VFArticleMetadataandVFSettingsobjects. 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)- Add
VFPreviewCommentsViewto your view. PassonLoginto present your authentication flow andonActionto handle user actions. Drop the view anywhere in aScrollVieworVStack; 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 }
)
}
}
}| Parameter | Type | Description |
|---|---|---|
onLogin | () -> Void | Called 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 |
onAction | VFActionsCallbacks | Called when the user taps an action such as writing a comment or opening a profile. Same callback type as setActionCallbacks in UIKit. |
theme | VFTheme? | Optional. Defaults to following the SwiftUI colorScheme, so dark mode is handled automatically. |
autoSize | Bool | Optional, defaults to true. The view sets its own frame height as the content changes. Set to false to control the height yourself. |
onHeightChange | (CGFloat) -> Void | Optional. Called with the new content height, equivalent to VFLayoutDelegate in UIKit. Only needed when autoSize is false. |
- 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
}
})Updated about 4 hours ago
