
èšèª ð¯ðµ æ¥æ¬èª
ããã¥ã¡ã³ã
ã¯ããã«
èªèšŒ
äœ¿çšæ¹æ³
Add Comments to Your iOS App
ãã㯠FastComments ã®å ¬åŒ iOS ã©ã€ãã©ãªã§ãã
iOS ã¢ããªã«ã©ã€ãã³ã¡ã³ãããã£ãããã¬ãã¥ãŒã®ãŠã£ãžã§ãããåã蟌ãããšãã§ããŸãã
ãªããžããª
æ©èœ 
- ãã¹ããããè¿ä¿¡ãšããŒãžããŒã·ã§ã³ãåããã¹ã¬ãã圢åŒã®ã³ã¡ã³ãããªãŒ
- æçš¿äœæããªã¢ã¯ã·ã§ã³ãã¡ãã£ã¢æ·»ä»ãåãããœãŒã·ã£ã«ãã£ãŒã
- èªåã¹ã¯ããŒã«ãšæ¥ä»åºåããåããã©ã€ããã£ããã¢ãŒã
- WebSocket ãä»ãããªã¢ã«ã¿ã€ã æŽæ°ïŒæ°ããã³ã¡ã³ããæç¥šããã¬ãŒã³ã¹ïŒ
- ã·ã³ã°ã«ãµã€ã³ãªã³ïŒãã¹ãçšã®ç°¡æ SSOãéçšåãã®ã»ãã¥ã¢ SSOïŒ
- 倪åãæäœãã³ãŒãã@ã¡ã³ã·ã§ã³ãå«ããªããããã¹ãç·šé
- èšå®å¯èœãªã¹ã¿ã€ã«ïŒäž/äžã®ç¢å°ãŸãã¯ããŒãïŒãæã€æç¥šæ©èœ
- ã¢ãã¬ãŒã·ã§ã³æäœïŒãã©ã°ããã³ãããã¯ããããã¯
- ããªã»ãããšãã«ã«ã¹ã¿ãã€ãºãåããå æ¬çãªããŒã
- ã³ã¡ã³ããšãã£ãŒãæçš¿äœæã®ããã®ã«ã¹ã¿ã ããŒã«ããŒãã¿ã³
- ç»åã¢ããããŒã
- EUãªãŒãžã§ã³ã®ãµããŒã
- ãŠãŒã¶ãŒã®ãã¬ãŒã³ã¹ïŒãªã³ã©ã€ã³/ãªãã©ã€ã³è¡šç€ºïŒ
- ã¿ã°ããŒã¹ã®ãã£ãŒããã£ã«ã¿ãªã³ã°
- ããŒã«ãªãŒãŒã·ã§ã³ã®ãµããŒã
ã€ã³ã¹ããŒã« 
Swift Package Managerã䜿çšããŠFastCommentsUIããããžã§ã¯ãã«è¿œå ããŸãã
Xcodeã§: File > Add Package Dependencies ãéžæãããªããžããªã®URLãå ¥åããŸãã
ãŸãã¯ãPackage.swift ã«è¿œå ããŸã:
dependencies: [
.package(url: "https://github.com/fastcomments/fastcomments-ios.git", from: "1.0.0")
]
次ã«ãã¿ãŒã²ããã«è£œåã远å ããŸã:
.target(
name: "YourApp",
dependencies: [
.product(name: "FastCommentsUI", package: "fastcomments-ios")
]
)
å¿ èŠãªç®æã§äž¡æ¹ã®ã¢ãžã¥ãŒã«ãã€ã³ããŒãããŸã:
import FastCommentsUI
import FastCommentsSwift
ã¯ã€ãã¯ã¹ã¿ãŒã 
ã³ã¡ã³ããŠã£ãžã§ããã衚瀺ããããã®æå°éã®ã»ããã¢ãã:
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()
}
}
}
"demo" ãããªãã® FastComments ããã³ã ID ã«çœ®ãæããŠãã ãããurlId ã¯ã³ã¡ã³ããä¿åãããããŒãžãŸãã¯ã¹ã¬ãããèå¥ããŸãã
èªèšŒïŒSSOïŒ 
FastComments 㯠3 ã€ã®èªèšŒã¢ãŒãããµããŒãããŠããŸã:
- Anonymous -- SSO ããŒã¯ã³ãªã; ãŠãŒã¶ãŒã¯ã»ãã·ã§ã³ããŒã¹ã®èå¥ãååŸããŸã
- Simple SSO -- ãã¢ããã¹ãçšã®ã¯ã©ã€ã¢ã³ãåŽããŒã¯ã³ïŒå®å šã§ã¯ãããŸããïŒ
- Secure SSO -- æ¬çªåãã®ãµãŒããŒçœ²åããŒã¯ã³
Simple SSO
ãã¢ãããŒã«ã«ãã¹ãã«äŸ¿å©ã§ããSimple SSO ã§ã¯èª°ã§ãä»»æã®ãŠãŒã¶ãŒããªãããŸãããšãã§ãããããæ¬çªç°å¢ã§ã¯äœ¿çšããªãã§ãã ããã
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 ã¯æ¬¡ã®ãªãã·ã§ã³ãã£ãŒã«ãããµããŒãããŸã:
id-- ãŠãŒã¶ãŒ IDïŒæªèšå®ã®å Žå㯠email ãããã©ã«ãïŒdisplayName-- åå¥ã®è¡šç€ºådisplayLabel-- ååã®æšªã«è¡šç€ºãããã«ã¹ã¿ã ã©ãã«ïŒäŸ: "VIP"ïŒwebsiteUrl-- ãŠãŒã¶ãŒåã«ä»ããªã³ã¯locale-- ãã±ãŒã«ã³ãŒãisProfileActivityPrivate-- ãããã¡ã€ã«ã¢ã¯ãã£ããã£ãé衚瀺ã«ããïŒããã©ã«ã㯠trueïŒ
Secure SSO
æ¬çªç°å¢ã§ã¯ãããã¯ãšã³ãã API ã·ãŒã¯ã¬ããã䜿ã£ãŠçœ²åä»ã SSO ããŒã¯ã³ãçæããŸããiOS ã¢ããªã¯ãµãŒããŒãããã®ããŒã¯ã³ãååŸããconfig ã«æž¡ããŸãã
ããã¯ãšã³ãåŽïŒFastComments Swift SDK ãŸãã¯ä»»æã®èšèªã䜿çšïŒ:
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()
// ãã®ããŒã¯ã³ã API çµç±ã§ iOS ã¢ããªã«è¿ããŸã
iOS ã¢ããªå ã§:
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 {
// ããã¯ãšã³ãããããŒã¯ã³ãååŸ
let token = try? await fetchSSOTokenFromYourBackend()
// ããŒã¯ã³ã§æ°ãã config ãäœæããããããŒãåã«èšå®ãã
isLoadingToken = false
try? await sdk.load()
}
}
}
SecureSSOUserData ã¯è¿œå ã®ãã£ãŒã«ãããµããŒãããŸã:
optedInNotifications-- ã¡ãŒã«éç¥ã®ãªããã€ã³displayLabel-- ã«ã¹ã¿ã ã©ãã«displayName-- 衚瀺åwebsiteUrl-- ãŠã§ããµã€ãã® URLgroupIds-- ã°ã«ãŒãæå±isAdmin-- 管çè æš©éisModerator-- ã¢ãã¬ãŒã¿ãŒæš©éisProfileActivityPrivate-- ãããã£ãŒã«ã®éå ¬éèšå®
ã¹ã¬ããã³ã¡ã³ã 
åºæ¬çãªäœ¿çšæ³
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()
}
}
}
æç¥šã¹ã¿ã€ã«
ããã©ã«ãã®æç¥šã¹ã¿ã€ã«ã¯äžäžã®ç¢å°ã衚瀺ããŸããããŒãåã®æç¥šã«ããã«ã¯ ._1 ãæž¡ããŸã:
FastCommentsView(sdk: sdk, voteStyle: ._1)
| Style | å€èг |
|---|---|
._0 |
Up/down arrow buttons with net count |
._1 |
Single heart button with count |
ã€ãã³ãã³ãŒã«ããã¯
ã¢ãã£ãã¡ã€ã¢åœ¢åŒã®ã³ãŒã«ããã¯ã䜿ã£ãŠãŠãŒã¶ãŒæäœãåŠçããŸã:
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 㯠.name ãŸã㯠.avatar ã§ã
print("Tapped \(userInfo.displayName)")
}
ããŒãã®é©çš
SwiftUI ã®ç°å¢ãéããŠããŒããæž¡ããŸã:
FastCommentsView(sdk: sdk)
.fastCommentsTheme(myTheme)
.task { try? await sdk.load() }
ãŸã㯠SDK ã«çŽæ¥èšå®ããŸã:
sdk.theme = FastCommentsTheme.modern
ãœãŒãæ¹å
sdk.defaultSortDirection = .nf // æ°ããé ïŒããã©ã«ãïŒ
sdk.defaultSortDirection = .of // å€ãé
sdk.defaultSortDirection = .mr // æãé¢é£æ§ã®é«ã
ã©ã€ããã£ãã 
LiveChatViewã¯èªåã¹ã¯ããŒã«ãæ¥ä»åºåããã³ã³ãã¯ããªã¬ã€ã¢ãŠããåãããªã¢ã«ã¿ã€ã ãã£ããäœéšãæäŸããŸããSDKãå€ãé ïŒoldest-firstïŒã®ãœãŒããšå³æã©ã€ã衚瀺çšã«èªåçã«æ§æããŸãã
struct ChatView: View {
@StateObject private var sdk: FastCommentsSDK = {
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "chat-room-1",
sso: ssoToken // ãŠãŒã¶ãŒã«ååã衚瀺ããããããSSOã®äœ¿çšãæšå¥šããŸã
)
return FastCommentsSDK(config: config)
}()
var body: some View {
LiveChatView(sdk: sdk)
.onCommentPosted { comment in
print("Sent: \(comment.commentHTML)")
}
.task {
try? await sdk.load()
}
}
}
LiveChatViewã¯æ¬¡ã®ã³ãŒã«ããã¯ããµããŒãããŸã:
.onCommentPosted-- ãŠãŒã¶ãŒãã¡ãã»ãŒãžãéä¿¡ãããšãã«åŒã³åºãããŸã.onCommentDeleted-- ã¡ãã»ãŒãžãåé€ããããšãã«åŒã³åºãããŸã.onUserClick-- ãŠãŒã¶ãŒã®ååãã¢ãã¿ãŒãã¿ããããããšãã«åŒã³åºãããŸã
ãœãŒã·ã£ã«ãã£ãŒã 
ãã£ãŒãã·ã¹ãã ã¯ç¬ç«ãã SDK (FastCommentsFeedSDK) ã§ãå°çšã®ãã¥ãŒãæã¡ãŸãã
Loading and Displaying the Feed
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
// å
±æã·ãŒãã衚瀺ãã
}
.onUserClick { context, userInfo, source in
// ãŠãŒã¶ãŒãããã£ãŒã«ãžé·ç§»ãã
}
.onMediaClick { mediaItem, index in
// å
šç»é¢ç»åãã¥ãŒã¢ã衚瀺ãã
}
.task {
try? await sdk.load()
}
}
}
The feed view includes pull-to-refresh and infinite scroll automatically.
Creating Posts
Use FeedPostCreateView to present a post creation form:
@State private var showCreatePost = false
// ãã¥ãŒã®æ¬æå
ã§:
.sheet(isPresented: $showCreatePost) {
FeedPostCreateView(
sdk: sdk,
onPostCreated: { post in
showCreatePost = false
Task { try? await sdk.refresh() }
},
onCancelled: {
showCreatePost = false
}
)
}
Reacting to Posts
The SDK handles reactions with optimistic updates:
try await sdk.reactPost(postId: post.id, reactionType: "l")
// ãªã¢ã¯ã·ã§ã³ç¶æ
ã確èªãã
let hasLiked = sdk.hasUserReacted(postId: post.id, reactType: "l")
let likeCount = sdk.getLikeCount(postId: post.id)
Opening Comments on a Post
Use CommentsSheet to display comments for a feed post. It creates a FastCommentsSDK instance internally using the feed SDK's config:
.sheet(item: $commentsPost) { post in
CommentsSheet(post: post, feedSDK: sdk, onUserClick: { context, userInfo, source in
// ãŠãŒã¶ãŒã¯ãªãã¯ãåŠçãã
})
}
Note: FeedPost must conform to Identifiable for .sheet(item:). Add this extension:
extension FeedPost: @retroactive Identifiable {}
Tag-Based Feed Filtering
Implement the TagSupplier protocol to filter feed posts by 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 nil for an unfiltered global feed.
Saving and Restoring Feed State
Preserve pagination state across view lifecycle events:
let state = sdk.savePaginationState()
// åŸã§...
sdk.restorePaginationState(state)
Deleting Posts
sdk.onPostDeleted = { postId in
print("Post \(postId) was deleted")
}
ããŒã 
ããŒãããªã»ãã
4ã€ã®çµã¿èŸŒã¿ããªã»ãããå©çšå¯èœã§ã:
// ã·ã¹ãã ã®ããã©ã«ã
sdk.theme = FastCommentsTheme.default
// 圱ä»ãã®ã«ãŒãã倧ããªè§äžž
sdk.theme = FastCommentsTheme.modern
// ãã©ããã圱ãªããå°ããªè§äžžãã¹ã¬ããç·ãªã
sdk.theme = FastCommentsTheme.minimal
// ãã¹ãŠã®ã¢ã¯ã·ã§ã³ã«ã©ãŒãåäžã®ãã©ã³ãã«ã©ãŒã«èšå®
sdk.theme = FastCommentsTheme.allPrimary(.indigo)
ã³ã¡ã³ã衚瀺ã¹ã¿ã€ã«
var theme = FastCommentsTheme()
theme.commentStyle = .flat // ä»åãä»ãã®ãã©ãããªã¹ãïŒããã©ã«ãïŒ
theme.commentStyle = .card // 圱ä»ãã®è§äžžã«ãŒã
theme.commentStyle = .bubble // ãã£ããããã«ã¹ã¿ã€ã«
ã«ã©ãŒ
ãã¹ãŠã®ã«ã©ãŒå±æ§ã¯ä»»æã§ããæªèšå®ã®å€ã¯é©åãªã·ã¹ãã ã®ããã©ã«ãã«ãã©ãŒã«ããã¯ããŸãã
var theme = FastCommentsTheme()
// ãã©ã³ãã«ã©ãŒ
theme.primaryColor = .indigo
theme.primaryLightColor = .indigo.opacity(0.6)
theme.primaryDarkColor = Color(red: 0.2, green: 0.1, blue: 0.5)
// èæ¯
theme.commentBackgroundColor = Color(.secondarySystemGroupedBackground)
theme.containerBackgroundColor = Color(.systemGroupedBackground)
// ã¢ã¯ã·ã§ã³ãã¿ã³
theme.actionButtonColor = .indigo
theme.replyButtonColor = .indigo
theme.toggleRepliesButtonColor = .indigo.opacity(0.8)
theme.loadMoreButtonTextColor = .indigo
// æç¥š
theme.voteActiveColor = .red
theme.voteCountColor = .primary
theme.voteCountZeroColor = .secondary
theme.voteDividerColor = Color(.separator)
// ãªã³ã¯
theme.linkColor = .indigo
theme.linkColorPressed = .indigo.opacity(0.5)
// ãã€ã¢ãã°
theme.dialogHeaderBackgroundColor = .indigo
theme.dialogHeaderTextColor = .white
// å
¥åããŒ
theme.inputBarBackgroundColor = Color(.systemBackground)
theme.inputBarBorderColor = Color(.separator)
// ãã®ä»
theme.onlineIndicatorColor = .green
theme.separatorColor = Color(.separator)
theme.badgeBackgroundColor = .gray.opacity(0.2)
theme.threadLineColor = .indigo.opacity(0.15)
ã¿ã€ãã°ã©ãã£
theme.commenterNameFont = .subheadline.weight(.bold)
theme.bodyFont = .body
theme.captionFont = .caption
theme.actionFont = .caption.weight(.medium)
ã¬ã€ã¢ãŠããšéé
theme.cornerRadius = .large // 䜿çšå¯èœ: .none, .small, .medium, .large
theme.commentSpacing = 4 // ã³ã¡ã³ãè¡éã®ãã€ã³ãæ°
theme.nestingIndent = 20 // ãã¹ãã¬ãã«ããšã®ã€ã³ãã³ãéïŒãã€ã³ãïŒ
theme.avatarSize = 36 // ã«ãŒãã³ã¡ã³ãã®ã¢ãã¿ãŒçŽåŸ
theme.replyAvatarSize = 28 // ãã¹ããããè¿ä¿¡ã®ã¢ãã¿ãŒçŽåŸ
èŠèŠå¹æ
theme.showShadows = true // ã«ãŒãã«èã圱ã衚瀺
theme.showThreadLine = true // ãã¹ããããè¿ä¿¡ãã€ãªãåçŽç·
theme.animateVotes = true // æç¥šå€æŽæã®ã¹ããªã³ã°ã¢ãã¡ãŒã·ã§ã³
ããŒãã®é©çš
2ã€ã®æ¹æ³:
// SwiftUI ã®ç°å¢çµç±ïŒãã¥ãŒéå±€ã«ã¯æšå¥šïŒ
FastCommentsView(sdk: sdk)
.fastCommentsTheme(theme)
// SDK ã«çŽæ¥èšå®
sdk.theme = theme
ã«ã¹ã¿ã ããŒã«ããŒã®ãã¿ã³ 
ã³ã¡ã³ãå ¥åããŒã«ããŒã®ãã¿ã³
ã³ã¡ã³ãå
¥åããŒã«ããŒã«ãã¿ã³ã远å ããã«ã¯ãCustomToolbarButtonãããã³ã«ãå®è£
ããŸã:
struct EmojiButton: CustomToolbarButton {
let id = "emoji"
let iconSystemName = "face.smiling" // SF ã·ã³ãã«å
let contentDescription = "Add Emoji"
let badgeText: String? = nil // ãªãã·ã§ã³ã®ãããžæ°
func onClick(text: Binding<String>) {
text.wrappedValue += "\u{1F44D}"
}
// ãªãã·ã§ã³ã®ãªãŒããŒã©ã€ãïŒããã©ã«ã㯠trueïŒ
func isEnabled() -> Bool { true }
func isVisible() -> Bool { true }
}
ãã¥ãŒäœææã«ã«ã¹ã¿ã ãã¿ã³ãæž¡ããŸã:
FastCommentsView(
sdk: sdk,
customToolbarButtons: [EmojiButton(), CodeBlockButton()]
)
ãŸã㯠SDK ã«ã°ããŒãã«ã«è¿œå ããŸãïŒãã¹ãŠã®ã€ã³ã¹ã¿ã³ã¹ã«é©çšïŒ:
sdk.addGlobalCustomToolbarButton(EmojiButton())
sdk.removeGlobalCustomToolbarButton(id: "emoji")
sdk.clearGlobalCustomToolbarButtons()
ãã£ãŒãããŒã«ããŒã®ãã¿ã³
æçš¿äœæãã©ãŒã çšã« FeedCustomToolbarButton ãå®è£
ããŸã:
struct HashtagButton: FeedCustomToolbarButton {
let id = "hashtag"
let iconSystemName = "number"
let contentDescription = "Add Hashtag"
func onClick(content: Binding<String>) {
content.wrappedValue += "#"
}
}
äœæãã¥ãŒã«æž¡ããŸã:
FeedPostCreateView(
sdk: sdk,
customToolbarButtons: [HashtagButton()],
onPostCreated: { _ in },
onCancelled: { }
)
ãŸãã¯ãã£ãŒã SDK ã«ã°ããŒãã«èšå®ããŸã:
sdk.globalFeedToolbarButtons = [HashtagButton()]
ã¢ãã¬ãŒã·ã§ã³ 
ãã¹ãŠã®ãŠãŒã¶ãŒãå©çšã§ããæäœ
- ãã©ã°ïŒãã©ã°è§£é€ -- ã³ã¡ã³ãã審æ»ã®ããã«å ±åãã
try await sdk.flagComment(commentId: commentId)
try await sdk.unflagComment(commentId: commentId)
- ãããã¯ïŒãããã¯è§£é€ -- ãŠãŒã¶ãŒã®ã³ã¡ã³ãããã¹ãŠé衚瀺ã«ããïŒé²èЧè åäœïŒ
try await sdk.blockUser(commentId: commentId)
try await sdk.unblockUser(commentId: commentId)
管çè å°çšã®æäœ
- ãã³çãïŒãã³è§£é€ -- ã³ã¡ã³ããã¹ã¬ããã®å é ã«åºå®ãã
try await sdk.pinComment(commentId: commentId)
try await sdk.unpinComment(commentId: commentId)
- ããã¯ïŒããã¯è§£é€ -- ã³ã¡ã³ããžã®æ°ããè¿ä¿¡ãçŠæ¢ãã
try await sdk.lockComment(commentId: commentId)
try await sdk.unlockComment(commentId: commentId)
ãã¹ãŠã®ã¢ãã¬ãŒã·ã§ã³æäœã¯ãUI ã®ã³ã¡ã³ãã³ã³ããã¹ãã¡ãã¥ãŒãããå©çšã§ããŸãã管çè
åãã®æäœã¯ãçŸåšã®ãŠãŒã¶ãŒããµã€ã管çè
ã§ããå Žåã«ã®ã¿è¡šç€ºãããŸãïŒSSO ã® isAdmin ãã©ã°ãŸãã¯ããã·ã¥ããŒãã®èšå®ã§æå®ïŒã
ãªã¢ã«ã¿ã€ã æŽæ° 
sdk.load() ãåŒã³åºããåŸãSDK ã¯æ§æããã urlId ã® WebSocket ã€ãã³ãã«èªåçã«è³ŒèªããŸããæ¬¡ã®ã€ãã³ããåŠçãããŸã:
- æ°ããã³ã¡ã³ããç·šéãåé€
- æç¥šïŒè¿œå ããã³åé€ïŒ
- ãã³ãããã¯ããã©ã°ããããã¯ã®ç¶æ 倿Ž
- ãŠãŒã¶ãŒã®ãã¬ãŒã³ã¹ïŒåå /éåºïŒ
- ã¹ã¬ããã®éé
- ãããžä»äž
- ãµãŒããŒæ§æã®æŽæ°
ã©ã€ã衚瀺ã®å¶åŸ¡
ããã©ã«ãã§ã¯ãä»ã®ãŠãŒã¶ãŒããã®æ°ããã³ã¡ã³ãã¯å³åº§ã«è¡šç€ºãããŸã:
sdk.showLiveRightAway = true // ããã©ã«ã: å³åº§ã«è¡šç€º
ããã false ã«èšå®ãããšãæ°ããã³ã¡ã³ãããNä»¶ã®æ°ããã³ã¡ã³ãããã¿ã³ã®èåŸã«ãããã¡ããããŠãŒã¶ãŒã衚瀺ã¿ã€ãã³ã°ãéžã¹ãããã«ãªããŸã:
sdk.showLiveRightAway = false
ãŠãŒã¶ãŒã®ãã¬ãŒã³ã¹
ãµãŒããŒããã¬ãŒã³ã¹è¿œè·¡ãæå¹ã«ãããšããŠãŒã¶ãŒã®ã¢ãã¿ãŒäžã«ãªã³ã©ã€ã³/ãªãã©ã€ã³ã®ã€ã³ãžã±ãŒã¿ãŒãèªåçã«è¡šç€ºãããŸããã¯ã©ã€ã¢ã³ãåŽã§ã®è¿œå èšå®ã¯äžèŠã§ãã
ããŒãžããŒã·ã§ã³ 
ããŒãžãµã€ãº
// ã³ã¡ã³ãïŒããã©ã«ãã¯30
sdk.pageSize = 50
// ãã£ãŒãïŒããã©ã«ãã¯10
feedSDK.pageSize = 20
ã³ã¡ã³ãã®è¿œå èªã¿èŸŒã¿
UIã¯ããŒãžããŒã·ã§ã³ã³ã³ãããŒã«ãèªåçã«è¡šç€ºããŸããããã°ã©ã ããããŒãžããŒã·ã§ã³ãããªã¬ãŒããããšãã§ããŸãïŒ
// 次ã®ããŒãžãèªã¿èŸŒã
try await sdk.loadMore()
// æ®ãããã¹ãŠèªã¿èŸŒãïŒããã©ãŒãã³ã¹ã®ããã³ã¡ã³ãã2000ä»¶ãè¶
ããå Žåã¯ç¡å¹ïŒ
try await sdk.loadAll()
// ç¶æ
ã確èª
sdk.hasMore // ããã«ããŒãžãååšãããã©ãã
sdk.shouldShowLoadAll()
sdk.getCountRemainingToShow()
åã³ã¡ã³ãã®ããŒãžããŒã·ã§ã³
ãã¹ããããè¿ä¿¡ã¯é å»¶èªã¿èŸŒã¿ãããŸãããŠãŒã¶ãŒãã¹ã¬ãããå±éãããšãæåã®5ä»¶ã®åã³ã¡ã³ããèªã¿èŸŒãŸããŸããããã«ååšããå Žåã¯ãè¿ä¿¡ãããã«èªã¿èŸŒããã³ã³ãããŒã«ã衚瀺ãããŸããããã¯UIã«ãã£ãŠèªåçã«åŠçãããŸãã
ç¶æ
ãšå¯èŠ³æž¬æ§ 
FastCommentsSDK ãš FastCommentsFeedSDK ã¯ã©ã¡ãã ObservableObject ã¯ã©ã¹ã§ã@Published ããããã£ãæã¡ãŸããããã㯠SwiftUI ã®ãã¥ãŒã§ç£èŠããŠãªã¢ã¯ãã£ã㪠UI æŽæ°ã«å©çšã§ããŸãã
FastCommentsSDK ã® @Published ããããã£
| ãããã㣠| å | 説æ |
|---|---|---|
commentCountOnServer |
Int |
ãµãŒããŒäžã®ã³ã¡ã³ãã®ç·æ° |
newRootCommentCount |
Int |
ãããã¡ãããæ°ããã³ã¡ã³ãïŒshowLiveRightAway ã false ã®ãšãïŒ |
currentUser |
UserSessionInfo? |
çŸåšèªèšŒãããŠãããŠãŒã¶ãŒ |
isSiteAdmin |
Bool |
çŸåšã®ãŠãŒã¶ãŒããµã€ã管çè ãã©ãã |
isClosed |
Bool |
ã³ã¡ã³ãã¹ã¬ãããéããããŠãããã©ãã |
hasBillingIssue |
Bool |
課éã«åé¡ããããã©ãã |
isLoading |
Bool |
ãããã¯ãŒã¯ãªã¯ãšã¹ããé²è¡äžãã©ãã |
hasMore |
Bool |
ããã«ããŒãžãååšãããã©ãã |
blockingErrorMessage |
String? |
UI ã®åäœã劚ãããšã©ãŒ |
warningMessage |
String? |
ããããã³ã°ããªãèŠåã¡ãã»ãŒãž |
isDemo |
Bool |
ãã¢ã¢ãŒãã§å®è¡ãããŠãããã©ãã |
commentsVisible |
Bool |
ã³ã¡ã³ã衚瀺ã®åãæ¿ã |
toolbarEnabled |
Bool |
æžåŒããŒã«ããŒã衚瀺ãããŠãããã©ãã |
FastCommentsFeedSDK ã® @Published ããããã£
| ãããã㣠| å | 説æ |
|---|---|---|
feedPosts |
[FeedPost] |
çŸåšèªã¿èŸŒãŸããŠãããã£ãŒãæçš¿ |
hasMore |
Bool |
ããã«ããŒãžãååšãããã©ãã |
currentUser |
UserSessionInfo? |
çŸåšèªèšŒãããŠãããŠãŒã¶ãŒ |
blockingErrorMessage |
String? |
ããããã³ã°ãšã©ãŒã®ã¡ãã»ãŒãž |
isLoading |
Bool |
ãããã¯ãŒã¯ãªã¯ãšã¹ããé²è¡äžãã©ãã |
newPostsCount |
Int |
ååã®èªã¿èŸŒã¿ä»¥éã®æ°ããæçš¿æ° |
ã³ã¡ã³ãããªãŒ
ã³ã¡ã³ãããªãŒã¯ sdk.commentsTree ã§ã¢ã¯ã»ã¹ã§ããŸã:
// ã¬ã³ããªã³ã°çšã®è¡šç€ºãããŠããããŒãã®ãã©ãããªäžèЧ
sdk.commentsTree.visibleNodes
// IDã§ã³ã¡ã³ããæ€çŽ¢
sdk.commentsTree.commentsById["comment-id"]
EUãªãŒãžã§ã³ 
EU ããŒã¿ã»ã³ã¿ãŒã䜿çšããã«ã¯ãèšå®ã® region ãã£ãŒã«ããèšå®ããŠãã ãã:
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-page",
region: "eu"
)
ããã«ããããã¹ãŠã® API ãªã¯ãšã¹ããš WebSocket æ¥ç¶ã eu.fastcomments.com ã«ã«ãŒãã£ã³ã°ãããŸãã
ã¯ãªãŒã³ã¢ãã 
SDKã€ã³ã¹ã¿ã³ã¹ã®äœ¿çšãçµãã£ããïŒäŸ: ãã¥ãŒãéãããããšãïŒãWebSocketæ¥ç¶ãéããããã¯ã°ã©ãŠã³ãã¿ã¹ã¯ããã£ã³ã»ã«ããããã«cleanup()ãåŒã³åºããŠãã ãã:
sdk.cleanup()
SwiftUI ã® @StateObject ã«ãã£ãŠç®¡çãããŠãããã¥ãŒã§ã¯ãéåžžãã㯠.onDisappear å
ããŸãã¯ãã¥ãŒãè§£æŸããããšãã«åŒã³åºãããŸãã
ç»åã¢ããããŒã 
ã³ã¡ã³ã
let imageUrl = try await sdk.uploadImage(imageData: jpegData, filename: "photo.jpg")
ã¢ããããŒããããç»åã®URLæååãè¿ããŸãã
ãã£ãŒãæçš¿
let mediaItem = try await feedSDK.uploadImage(imageData: jpegData, filename: "photo.jpg")
// è€æ°ã®ç»åã䞊åã«ã¢ããããŒããã
let mediaItems = try await feedSDK.uploadImages(images: [
(jpegData1, "photo1.jpg"),
(jpegData2, "photo2.jpg")
])
ãŠãŒã¶ãŒã¡ã³ã·ã§ã³ 
@ã¡ã³ã·ã§ã³ã®ãªãŒãã³ã³ããªãŒãããµããŒããããŠãŒã¶ãŒãæ€çŽ¢:
let results = try await sdk.searchUsers(query: "jan")
// [UserSearchResult] ãè¿ããŸãïŒuserIdãusernameãavatar ãªã©ïŒ
çµã¿èŸŒã¿ã® CommentInputBar 㯠@ã¡ã³ã·ã§ã³ã®ãªãŒãã³ã³ããªãŒããèªåçã«åŠçããŸãã
ã³ã¡ã³ãã®ç·šéãšåé€ 
ç·šé
try await sdk.editComment(commentId: commentId, newText: "Updated text")
ãµãŒããŒãHTMLãåã¬ã³ããªã³ã°ããŸããããŒã«ã«ã®ã³ã¡ã³ãã¯èªåçã«æŽæ°ãããŸãã
åé€
try await sdk.deleteComment(commentId: commentId)
ã³ã¡ã³ããåé€ãããšããã®åå«ãããŒã«ã«ããªãŒããåé€ãããŸãã
ãããã®æäœã¯ãçŸåšã®ãŠãŒã¶ãŒãã³ã¡ã³ãã®äœæè ïŒãŸãã¯ãµã€ã管çè ïŒã®å ŽåãUIã®ã³ã¡ã³ãã³ã³ããã¹ãã¡ãã¥ãŒããå©çšã§ããŸãã
ãšã©ãŒåŠç 
SDK ã®ã¡ãœãã㯠FastCommentsError ãã¹ããŒããŸãããã㯠LocalizedError ã«æºæ ããŠããŸã:
do {
try await sdk.load()
} catch let error as FastCommentsError {
print(error.translatedError ?? error.reason ?? "Unknown error")
} catch {
print(error.localizedDescription)
}
FastCommentsError ã®ããããã£:
code-- API ããã®ãšã©ãŒã³ãŒãreason-- è±èªã®ãšã©ãŒèª¬ætranslatedError-- ãµãŒããŒããæäŸãããããŒã«ã©ã€ãºããããšã©ãŒã¡ãã»ãŒãž
ããããã³ã°ãšã©ãŒã¯ sdk.blockingErrorMessage ãéããŠèªåçã«éç¥ãããçµã¿èŸŒã¿ã®ãã¥ãŒããŠãŒã¶ãŒã«è¡šç€ºããŸãã
ããŒã«ãªãŒãŒã·ã§ã³ 
ãµãŒããŒæäŸã®æååãããŒã«ã©ã€ãºããã«ã¯ãconfig ã«ãã±ãŒã«ã³ãŒããæž¡ããŸãïŒ
let config = FastCommentsWidgetConfig(
tenantId: "YOUR_TENANT_ID",
urlId: "my-page",
locale: "fr_fr"
)
ã¯ã©ã€ã¢ã³ãåŽã® UI æåå㯠iOS ã®ãã³ãã«ããŒã¹ã®ããŒã«ãªãŒãŒã·ã§ã³ã䜿çšããŸãã
ãµã³ãã«ã¢ã㪠
ãã®ãªããžããªã«ã¯ãExampleApp/ ã«å®å
šãªãµã³ãã«ã¢ããªãå«ãŸããŠããã以äžã®ãã¢ã瀺ããŠããŸã:
- ã¹ã¬ããåãããã³ã¡ã³ãïŒSSOããã³ã«ã¹ã¿ã ããŒã察å¿ïŒ
- æçš¿äœæãšã¿ã°ãã£ã«ã¿ãªã³ã°ãåãããœãŒã·ã£ã«ãã£ãŒã
- ã©ã€ããã£ãã
- ã·ã³ãã«ãã€å®å šãªSSOãããŒ
- ã«ã¹ã¿ã ããŒã«ããŒãã¿ã³ïŒã³ã¡ã³ãããã³ãã£ãŒãïŒ
ãã«ããå¿ èŠã§ããïŒ
iOS Library ã«é¢ããŠåé¡ãçºçããå Žåã質åãããå Žåã¯ã次ã®ãããããè¡ã£ãŠãã ããïŒ
è²¢ç®
è²¢ç®ãæè¿ããŸãïŒã³ã³ããªãã¥ãŒã·ã§ã³ã®ã¬ã€ãã©ã€ã³ã«ã€ããŠã¯ãGitHub ãªããžããªãã芧ãã ããã