
Sprog 🇩🇰 Dansk
Dokumentation
Kom godt i gang
Autentificering
Anvendelse
Add Comments to Your iOS App
Dette er det officielle iOS-bibliotek for FastComments.
Integrer live-kommentarer, chat og anmeldelses-widgets i din iOS-app.
Arkiv
Funktioner 
- Trådede kommentartræer med indlejrede svar og sideinddeling
- Socialt feed med oprettelse af indlæg, reaktioner og medievedhæftninger
- Live chat-tilstand med automatisk rulning og dataseparatorer
- Realtidsopdateringer via WebSocket (nye kommentarer, stemmer, tilstedeværelse)
- Single Sign-On (Simple SSO til test, Secure SSO til produktion)
- Rig tekstredigering med fed, kursiv, kode og @mentions
- Afstemning med konfigurerbare stilarter (op-/ned-pile eller hjerter)
- Moderationshandlinger: marker, fastgør, lås, bloker
- Omfattende temaindstillinger med forudindstillinger og fuld tilpasning
- Egendefinerede værktøjslinjeknapper til kommentarer og oprettelse af feed-indlæg
- Upload af billeder
- Understøttelse af EU-regionen
- Brugertilstedeværelse (online/offline-indikatorer)
- Tag-baseret feedfiltrering
- Understøttelse af lokalisering
Installation 
Tilføj FastCommentsUI til dit projekt ved hjælp af Swift Package Manager.
I Xcode: Arkiv > Tilføj pakkeafhængigheder, indtast derefter repository-URL'en.
Eller tilføj det til din Package.swift:
dependencies: [
.package(url: "https://github.com/fastcomments/fastcomments-ios.git", from: "1.0.0")
]
Then add the product to your target:
.target(
name: "YourApp",
dependencies: [
.product(name: "FastCommentsUI", package: "fastcomments-ios")
]
)
Import both modules where needed:
import FastCommentsUI
import FastCommentsSwift
Hurtig start 
Den minimale opsætning for at vise en kommentar-widget:
import SwiftUI
import FastCommentsUI
struct ContentView: View {
@StateObject private var sdk = FastCommentsSDK(
config: FastCommentsWidgetConfig(
tenantId: "demo",
urlId: "my-page-1",
url: "https://example.com/page-1",
pageTitle: "My Page"
)
)
var body: some View {
FastCommentsView(sdk: sdk)
.task {
try? await sdk.load()
}
}
}
Udskift "demo" med dit FastComments tenant-id. urlId identificerer siden eller tråden, hvor kommentarerne gemmes.
Autentificering (SSO) 
FastComments understøtter tre autentificeringsmetoder:
- Anonym -- ingen SSO-token; brugere får sessionbaserede identiteter
- Simpel SSO -- klientside-token til demoer og test (ikke sikker)
- Sikker SSO -- serversigneret token til produktion
Simpel SSO
Brugbar til demoer og lokal testning. Alle kan udgive sig for en hvilken som helst bruger med Simpel SSO, så brug det ikke i produktion.
import FastCommentsSwift
let userData = SimpleSSOUserData(
username: "Jane Doe",
email: "jane@example.com",
avatar: "https://example.com/avatar.jpg"
)
let sso = FastCommentsSSO.createSimple(simpleSSOUserData: userData)
let token = try? sso.prepareToSend()
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-page-1",
sso: token
)
let sdk = FastCommentsSDK(config: config)
SimpleSSOUserData understøtter også valgfrie felter:
id-- bruger-id (som standard e-mail hvis ikke angivet)displayName-- separat visningsnavndisplayLabel-- brugerdefineret label vist ved siden af navnet (f.eks. "VIP")websiteUrl-- link på brugerens navnlocale-- locale-kodeisProfileActivityPrivate-- skjuler profilaktivitet (som standard true)
Sikker SSO
I produktion genererer din backend et signerede SSO-token ved hjælp af din API-secret. iOS-appen henter dette token fra din server og sender det til konfigurationen.
På din backend (ved brug af FastComments Swift SDK eller ethvert sprog):
let userData = SecureSSOUserData(
id: "user-123",
email: "user@example.com",
username: "Display Name",
avatar: "https://example.com/avatar.jpg"
)
let sso = try FastCommentsSSO.createSecure(apiKey: "YOUR_API_KEY", secureSSOUserData: userData)
let token = try sso.prepareToSend()
// Return this token to your iOS app via your API
I din iOS-app:
struct MyView: View {
@StateObject private var sdk = FastCommentsSDK(
config: FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-page-1"
)
)
@State private var isLoadingToken = true
var body: some View {
Group {
if isLoadingToken {
ProgressView("Loading...")
} else {
FastCommentsView(sdk: sdk)
}
}
.task {
// Fetch the token from your backend
let token = try? await fetchSSOTokenFromYourBackend()
// Create a new config with the token, or set it before load
isLoadingToken = false
try? await sdk.load()
}
}
}
SecureSSOUserData understøtter yderligere felter:
optedInNotifications-- tilvalg af e-mailnotifikationerdisplayLabel-- brugerdefineret labeldisplayName-- visningsnavnwebsiteUrl-- webadressegroupIds-- gruppe-medlemskaberisAdmin-- administratorrettighederisModerator-- moderatorrettighederisProfileActivityPrivate-- profilens privatliv
Trådede kommentarer 
Grundlæggende brug
struct CommentsPage: View {
@StateObject private var sdk = FastCommentsSDK(
config: FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "article-42",
url: "https://example.com/article/42",
pageTitle: "Article Title"
)
)
var body: some View {
FastCommentsView(sdk: sdk)
.task {
try? await sdk.load()
}
}
}
Stemmetyper
Standard stemmestil viser op-/ned-pile. Angiv ._1 for hjerte-stemmer:
FastCommentsView(sdk: sdk, voteStyle: ._1)
| Stil | Udseende |
|---|---|
._0 |
Op-/ned-pileknapper med nettetal |
._1 |
Enkel hjerteknap med antal |
Hændelses-callbacks
Brug callbacks i modifier-stil til at håndtere brugerinteraktioner:
FastCommentsView(sdk: sdk)
.onCommentPosted { comment in
print("New comment: \(comment.commentHTML)")
}
.onReplyClick { renderableComment in
print("Replying to: \(renderableComment.comment.id)")
}
.onUserClick { context, userInfo, source in
// source er .name eller .avatar
print("Tapped \(userInfo.displayName)")
}
Anvend et tema
Angiv et tema via SwiftUI-miljøet:
FastCommentsView(sdk: sdk)
.fastCommentsTheme(myTheme)
.task { try? await sdk.load() }
Eller indstil det direkte på SDK'en:
sdk.theme = FastCommentsTheme.modern
Sorteringsretning
sdk.defaultSortDirection = .nf // Nyeste først (standard)
sdk.defaultSortDirection = .of // Ældste først
sdk.defaultSortDirection = .mr // Mest relevante
Livechat 
LiveChatView giver en realtids chatoplevelse med automatisk rulning, datoseparatorer og et kompakt layout. Den konfigurerer SDK'en automatisk til ældste-først sortering og øjeblikkelig live-visning.
struct ChatView: View {
@StateObject private var sdk: FastCommentsSDK = {
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "chat-room-1",
sso: ssoToken // SSO anbefales, så brugerne har navne
)
return FastCommentsSDK(config: config)
}()
var body: some View {
LiveChatView(sdk: sdk)
.onCommentPosted { comment in
print("Sent: \(comment.commentHTML)")
}
.task {
try? await sdk.load()
}
}
}
LiveChatView supports these callbacks:
.onCommentPosted-- udløses, når brugeren sender en besked.onCommentDeleted-- udløses, når en besked slettes.onUserClick-- udløses, når en brugers navn eller avatar trykkes på
Socialt feed 
Feed-systemet er et separat SDK (FastCommentsFeedSDK) med sin egen visning.
Indlæsning og visning af feedet
struct FeedPage: View {
@StateObject private var sdk: FastCommentsFeedSDK = {
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-feed",
sso: ssoToken
)
return FastCommentsFeedSDK(config: config)
}()
@State private var commentsPost: FeedPost?
var body: some View {
FastCommentsFeedView(sdk: sdk)
.onPostSelected { post in
commentsPost = post
}
.onCommentsRequested { post in
commentsPost = post
}
.onSharePost { post in
// Vis delingsark
}
.onUserClick { context, userInfo, source in
// Naviger til brugerprofil
}
.onMediaClick { mediaItem, index in
// Vis billedviser i fuld skærm
}
.task {
try? await sdk.load()
}
}
}
Feed-visningen inkluderer pull-to-refresh og automatisk uendelig scroll.
Oprette indlæg
Brug FeedPostCreateView til at vise en formular til oprettelse af indlæg:
@State private var showCreatePost = false
// In your view body:
.sheet(isPresented: $showCreatePost) {
FeedPostCreateView(
sdk: sdk,
onPostCreated: { post in
showCreatePost = false
Task { try? await sdk.refresh() }
},
onCancelled: {
showCreatePost = false
}
)
}
Reagere på indlæg
SDK'en håndterer reaktioner med optimistiske opdateringer:
try await sdk.reactPost(postId: post.id, reactionType: "l")
// Check reaction state
let hasLiked = sdk.hasUserReacted(postId: post.id, reactType: "l")
let likeCount = sdk.getLikeCount(postId: post.id)
Åbne kommentarer for et indlæg
Brug CommentsSheet til at vise kommentarer for et feed-indlæg. Den opretter internt en FastCommentsSDK-instans ved hjælp af feed-SDK'ens konfiguration:
.sheet(item: $commentsPost) { post in
CommentsSheet(post: post, feedSDK: sdk, onUserClick: { context, userInfo, source in
// Håndter klik på bruger
})
}
Bemærk: FeedPost skal overholde Identifiable for .sheet(item:). Tilføj denne extension:
extension FeedPost: @retroactive Identifiable {}
Tag-baseret filtrering af feed
Implementer TagSupplier-protokollen for at filtrere feed-indlæg efter tags:
struct TeamTagSupplier: TagSupplier {
func getTags(currentUser: UserSessionInfo?) -> [String]? {
guard let user = currentUser else { return nil }
return ["team:\(user.id ?? "")", "public"]
}
}
sdk.tagSupplier = TeamTagSupplier()
Returnér nil for et ufiltreret globalt feed.
Gemme og gendanne feed-tilstand
Bevar pagineringsstatus på tværs af visningens livscyklus-begivenheder:
let state = sdk.savePaginationState()
// Later...
sdk.restorePaginationState(state)
Slette indlæg
sdk.onPostDeleted = { postId in
print("Post \(postId) was deleted")
}
Tema 
Tema-præindstillinger
Fire indbyggede præindstillinger er tilgængelige:
// Systemstandarder
sdk.theme = FastCommentsTheme.default
// Kort med skygger og store afrundede hjørner
sdk.theme = FastCommentsTheme.modern
// Fladt, ingen skygger, lille hjørneradius, ingen trådlinjer
sdk.theme = FastCommentsTheme.minimal
// Sæt alle handlingsfarver til en enkelt brandfarve
sdk.theme = FastCommentsTheme.allPrimary(.indigo)
Kommentarvisningsstilarter
var theme = FastCommentsTheme()
theme.commentStyle = .flat // Flad liste med skillelinjer (standard)
theme.commentStyle = .card // Afrundede kort med skygger
theme.commentStyle = .bubble // Chatboble-stil
Farver
Alle farveegenskaber er valgfrie. Udefinerede værdier vender tilbage til fornuftige systemstandarder.
var theme = FastCommentsTheme()
// Brandfarver
theme.primaryColor = .indigo
theme.primaryLightColor = .indigo.opacity(0.6)
theme.primaryDarkColor = Color(red: 0.2, green: 0.1, blue: 0.5)
// Baggrunde
theme.commentBackgroundColor = Color(.secondarySystemGroupedBackground)
theme.containerBackgroundColor = Color(.systemGroupedBackground)
// Handlingsknapper
theme.actionButtonColor = .indigo
theme.replyButtonColor = .indigo
theme.toggleRepliesButtonColor = .indigo.opacity(0.8)
theme.loadMoreButtonTextColor = .indigo
// Stemmer
theme.voteActiveColor = .red
theme.voteCountColor = .primary
theme.voteCountZeroColor = .secondary
theme.voteDividerColor = Color(.separator)
// Links
theme.linkColor = .indigo
theme.linkColorPressed = .indigo.opacity(0.5)
// Dialoger
theme.dialogHeaderBackgroundColor = .indigo
theme.dialogHeaderTextColor = .white
// Indtastningsbjælke
theme.inputBarBackgroundColor = Color(.systemBackground)
theme.inputBarBorderColor = Color(.separator)
// Andre
theme.onlineIndicatorColor = .green
theme.separatorColor = Color(.separator)
theme.badgeBackgroundColor = .gray.opacity(0.2)
theme.threadLineColor = .indigo.opacity(0.15)
Typografi
theme.commenterNameFont = .subheadline.weight(.bold)
theme.bodyFont = .body
theme.captionFont = .caption
theme.actionFont = .caption.weight(.medium)
Layout og mellemrum
theme.cornerRadius = .large // .none, .small, .medium, .large
theme.commentSpacing = 4 // Punkter mellem kommentarrækker
theme.nestingIndent = 20 // Antal punkter til indrykning pr. niveau
theme.avatarSize = 36 // Avatardiameter for topniveau-kommentarer
theme.replyAvatarSize = 28 // Avatardiameter for indlejrede svar
Visuelle effekter
theme.showShadows = true // Diskrete skygger på kort
theme.showThreadLine = true // Lodret linje, der forbinder indlejrede svar
theme.animateVotes = true // Spring-animation ved stemmeændringer
Anvendelse af temaer
To tilgange:
// Via SwiftUI-miljøet (anbefales til visningshierarki)
FastCommentsView(sdk: sdk)
.fastCommentsTheme(theme)
// Direkte på SDK'en
sdk.theme = theme
Brugerdefinerede knapper på værktøjslinjen 
Kommentarværktøjslinje-knapper
Implementer CustomToolbarButton-protokollen for at tilføje knapper til kommentarfeltets værktøjslinje:
struct EmojiButton: CustomToolbarButton {
let id = "emoji"
let iconSystemName = "face.smiling" // SF Symbol-navn
let contentDescription = "Add Emoji"
let badgeText: String? = nil // Valgfri badge-tæller
func onClick(text: Binding<String>) {
text.wrappedValue += "\u{1F44D}"
}
// Valgfrie overrides (standard er true)
func isEnabled() -> Bool { true }
func isVisible() -> Bool { true }
}
Videregiv brugerdefinerede knapper, når du opretter visningen:
FastCommentsView(
sdk: sdk,
customToolbarButtons: [EmojiButton(), CodeBlockButton()]
)
Eller tilføj dem globalt på SDK'et (gælder for alle forekomster):
sdk.addGlobalCustomToolbarButton(EmojiButton())
sdk.removeGlobalCustomToolbarButton(id: "emoji")
sdk.clearGlobalCustomToolbarButtons()
Feed-værktøjslinjeknapper
Implementer FeedCustomToolbarButton til indlægsoprettelsesformularen:
struct HashtagButton: FeedCustomToolbarButton {
let id = "hashtag"
let iconSystemName = "number"
let contentDescription = "Add Hashtag"
func onClick(content: Binding<String>) {
content.wrappedValue += "#"
}
}
Videregiv dem til oprettelsesvisningen:
FeedPostCreateView(
sdk: sdk,
customToolbarButtons: [HashtagButton()],
onPostCreated: { _ in },
onCancelled: { }
)
Eller indstil dem globalt på feed-SDK'et:
sdk.globalFeedToolbarButtons = [HashtagButton()]
Moderering 
Handlinger tilgængelige for alle brugere
- Flag/Unflag -- anmeld en kommentar til gennemgang
try await sdk.flagComment(commentId: commentId)
try await sdk.unflagComment(commentId: commentId)
- Block/Unblock -- skjul alle kommentarer fra en bruger (for hver enkelt seer)
try await sdk.blockUser(commentId: commentId)
try await sdk.unblockUser(commentId: commentId)
Handlinger kun for administratorer
- Pin/Unpin -- fastgør en kommentar til toppen af tråden
try await sdk.pinComment(commentId: commentId)
try await sdk.unpinComment(commentId: commentId)
- Lock/Unlock -- forhindre nye svar på en kommentar
try await sdk.lockComment(commentId: commentId)
try await sdk.unlockComment(commentId: commentId)
Alle moderationshandlinger er også tilgængelige gennem kommentarens kontekstmenu i brugergrænsefladen. Admin-handlinger vises kun, når den aktuelle bruger er site-admin (angivet via SSO isAdmin-flaget eller dashboard-konfiguration).
Opdateringer i realtid 
Efter at have kaldt sdk.load(), abonnerer SDK'en automatisk på WebSocket-begivenheder for den konfigurerede urlId. Følgende begivenheder håndteres:
- Nye kommentarer, redigeringer og sletninger
- Stemmer (nye og fjernede)
- Ændringer i pin-, låse-, flag- og blokeringstilstande
- Bruger-tilstedeværelse (tilslutning/forladelse)
- Tråd åben/lukket
- Tildeling af badges
- Opdateringer af serverkonfigurationen
Styring af livevisning
Som standard vises nye kommentarer fra andre brugere med det samme:
sdk.showLiveRightAway = true // Standard: vises med det samme
Sæt dette til false for at bufre nye kommentarer bag en "N nye kommentarer"-knap, så brugeren kan vælge, hvornår de skal vises:
sdk.showLiveRightAway = false
Bruger-tilstedeværelse
Online-/offlineindikatorer vises automatisk på brugeravatarer, når serveren aktiverer tilstedeværelsessporing. Der kræves ingen yderligere konfiguration på klienten.
Sideinddeling 
Sidestørrelse
// Kommentarer: standard 30
sdk.pageSize = 50
// Feed: standard 10
feedSDK.pageSize = 20
Indlæsning af flere kommentarer
Brugergrænsefladen viser pagineringskontroller automatisk. Du kan også udløse paginering programmatisk:
// Indlæs næste side
try await sdk.loadMore()
// Indlæs alle resterende (deaktiveret hvis >2000 kommentarer af hensyn til ydeevne)
try await sdk.loadAll()
// Kontroller status
sdk.hasMore // Whether more pages exist
sdk.shouldShowLoadAll()
sdk.getCountRemainingToShow()
Paginering af underkommentarer
Indlejrede svar indlæses efter behov. Når en bruger udvider en tråd, indlæses de første 5 underkommentarer. En "indlæs flere svar"-kontrol vises, hvis der er flere. Dette håndteres automatisk af brugergrænsefladen.
Tilstand og observabilitet 
Både FastCommentsSDK og FastCommentsFeedSDK er ObservableObject-klasser med @Published-egenskaber. Du kan observere disse i dine SwiftUI-visninger for reaktive UI-opdateringer.
FastCommentsSDK Publicerede Egenskaber
| Property | Type | Description |
|---|---|---|
commentCountOnServer |
Int |
Samlet antal kommentarer på serveren |
newRootCommentCount |
Int |
Bufferede nye kommentarer (når showLiveRightAway is false) |
currentUser |
UserSessionInfo? |
Nuværende autentificerede bruger |
isSiteAdmin |
Bool |
Om den aktuelle bruger er siteadministrator |
isClosed |
Bool |
Om kommentertråden er lukket |
hasBillingIssue |
Bool |
Om der er et betalingsproblem |
isLoading |
Bool |
Om en netværksanmodning er i gang |
hasMore |
Bool |
Om der findes flere sider med kommentarer |
blockingErrorMessage |
String? |
Fejl, der forhindrer brugergrænsefladen i at fungere |
warningMessage |
String? |
Ikke-blokerende advarselsmeddelelse |
isDemo |
Bool |
Om der køres i demotilstand |
commentsVisible |
Bool |
Om kommentarer er synlige |
toolbarEnabled |
Bool |
Om formateringsværktøjslinjen vises |
FastCommentsFeedSDK Publicerede Egenskaber
| Property | Type | Description |
|---|---|---|
feedPosts |
[FeedPost] |
Aktuelt indlæste feedindlæg |
hasMore |
Bool |
Om der findes flere sider |
currentUser |
UserSessionInfo? |
Nuværende autentificerede bruger |
blockingErrorMessage |
String? |
Blokerende fejlmeddelelse |
isLoading |
Bool |
Om en netværksanmodning er i gang |
newPostsCount |
Int |
Antal nye indlæg siden sidste indlæsning |
Kommentartræ
Kommentartræet kan tilgås via sdk.commentsTree:
// Flad liste over synlige noder til gengivelse
sdk.commentsTree.visibleNodes
// Find en kommentar efter ID
sdk.commentsTree.commentsById["comment-id"]
EU-region 
For at bruge EU-datacenteret skal du sætte feltet region i din konfiguration:
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-page",
region: "eu"
)
Dette dirigerer alle API-forespørgsler og WebSocket-forbindelser til eu.fastcomments.com.
Oprydning 
Når du er færdig med en SDK-instans (f.eks. når visningen lukkes), kald cleanup() for at lukke WebSocket-forbindelsen og annullere baggrundsopgaver:
sdk.cleanup()
For visninger styret af SwiftUI's @StateObject kaldes dette typisk i .onDisappear eller når visningen bliver deallokeret.
Upload af billeder 
Kommentarer
let imageUrl = try await sdk.uploadImage(imageData: jpegData, filename: "photo.jpg")
Returnerer URL-strengen for det uploadede billede.
Feed-indlæg
let mediaItem = try await feedSDK.uploadImage(imageData: jpegData, filename: "photo.jpg")
// Upload flere billeder parallelt
let mediaItems = try await feedSDK.uploadImages(images: [
(jpegData1, "photo1.jpg"),
(jpegData2, "photo2.jpg")
])
Brugernævnelser 
Søg efter brugere for at understøtte @mention-autofuldførelse:
let results = try await sdk.searchUsers(query: "jan")
// Returnerer [UserSearchResult] med userId, username, avatar osv.
Den indbyggede CommentInputBar håndterer @mention-autofuldførelse automatisk.
Redigering og sletning af kommentarer 
Rediger
try await sdk.editComment(commentId: commentId, newText: "Updated text")
Serveren renderer HTML'en igen. Den lokale kommentar opdateres automatisk.
Slet
try await sdk.deleteComment(commentId: commentId)
Sletning af en kommentar fjerner også dens efterkommere fra det lokale træ.
Begge handlinger er tilgængelige via kommentarens kontekstmenu i UI'en, når den aktuelle bruger er kommentarens forfatter (eller en webstedsadministrator).
Fejlhåndtering 
SDK-metoder kaster FastCommentsError, som overholder LocalizedError:
do {
try await sdk.load()
} catch let error as FastCommentsError {
print(error.translatedError ?? error.reason ?? "Unknown error")
} catch {
print(error.localizedDescription)
}
FastCommentsError egenskaber:
code-- fejlkode fra API'enreason-- engelsk fejlbeskrivelsetranslatedError-- lokaliseret fejlmeddelelse leveret af serveren
Blokeringsfejl vises også automatisk via sdk.blockingErrorMessage, som de indbyggede visninger viser for brugeren.
Lokalisering 
Angiv en lokalekode i konfigurationen for at lokalisere server-leverede strenge:
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-page",
locale: "fr_fr"
)
Klientside UI-strenge bruger iOS bundle-baseret lokalisering.
Eksempelapp 
Dette repository indeholder en komplet eksempel-app i ExampleApp/ med demonstrationer af:
- Trådede kommentarer med SSO og brugerdefinerede temaer
- Socialt feed med oprettelse af opslag og filtrering efter tags
- Live chat
- Enkle og sikre SSO-forløb
- Brugerdefinerede værktøjsknapper (kommentarer og feed)
Har du brug for hjælp?
Hvis du støder på problemer eller har spørgsmål om iOS-biblioteket, så:
Bidrag
Bidrag er velkomne! Besøg venligst GitHub-repositoriet for retningslinjer for bidrag.