FastComments.com

Додавање коментара у вашу iOS апликацију

Ово је званична iOS библиотека за FastComments.

Уграђујте видгете за уживо коментарисање, ћаскање и рецензије у вашу iOS апликацију.

Репозиторијум

Погледајте на GitHub


Функције Internal Link


  • Стабло коментара са угнежденим одговорима и пагинацијом
  • Друштвени фид са креирањем објава, реакцијама и прилозима медија
  • Режим уживо ћаскања са аутоматским скроловањем и раздвајачима датума
  • Ажурирања у реалном времену преко WebSocket-а (нови коментари, гласови, присутност)
  • Јединствено пријављивање (Simple SSO за тестирање, Secure SSO за продукцију)
  • Уређивање богатог текста са подебљаним, курзивом, кодом и @mentions
  • Гласање са конфигурисаним стиловима (стрелице горе/доле или срца)
  • Модерацијске акције: пријави, прикачи, закључај, блокирај
  • Свеобухватно подешавање тема са предефинисаним опцијама и потпуном прилагодбом
  • Прилагођена дугмад на алатној траци за коментаре и креирање објава у фиду
  • Отпремање слика
  • Подршка за EU регион
  • Присутност корисника (индикатори online/offline)
  • Филтрирање фида по ознакама
  • Подршка за локализацију

Захтеви Internal Link


  • iOS 16+ или macOS 14+
  • Swift 5.9+
  • SwiftUI

Инсталација Internal Link


Додајте FastCommentsUI у ваш пројекат користећи Swift Package Manager.

У Xcode-у: File > Add Package Dependencies, затим унесите URL репозиторијума.

Или га додајте у ваш Package.swift:

dependencies: [
    .package(url: "https://github.com/fastcomments/fastcomments-ios.git", from: "2.0.0")
]

Затим додајте производ у ваш циљ:

.target(
    name: "YourApp",
    dependencies: [
        .product(name: "FastCommentsUI", package: "fastcomments-ios")
    ]
)

Увезите оба модула где је потребно:

import FastCommentsUI
import FastCommentsSwift

Брзи почетак Internal Link

Минимално подешавање за приказ коментарског видгета:

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 tenant ID-ом. urlId идентификује страницу или нит (thread) у којој се чувају коментари.

Аутентификација (SSO) Internal Link

FastComments подржава три режима аутентификације:

  1. Anonymous -- нема SSO токена; корисници добијају идентитете засноване на сесији
  2. Simple SSO -- клијентски токен за демонстрације и тестирање (није безбедан)
  3. 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 корисника (подразумева се на адресу е-поште ако није подешено)
  • displayName -- посебно име за приказ
  • displayLabel -- прилагођена ознака приказана поред имена (нпр. "VIP")
  • websiteUrl -- веза на корисниково име
  • locale -- код локала
  • isProfileActivityPrivate -- сакриј активност профила (подразумевано true)

Secure SSO

У продукцији, ваш бекенд генерише потписан SSO токен користећи ваш API секрет. iOS апликација преузима овај токен са вашег сервера и прослеђује га у конфигурацију.

On your backend (using the FastComments Swift SDK or any language):

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()
// Вратите овај токен вашој iOS апликацији преко вашег API-ја

In your 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 {
            // Преузмите токен са вашег бекенда
            let token = try? await fetchSSOTokenFromYourBackend()
            // Креирајте нову конфигурацију са токеном, или је подесите пре учитавања
            isLoadingToken = false
            try? await sdk.load()
        }
    }
}

SecureSSOUserData подржава додатна поља:

  • optedInNotifications -- пријава за обавештења путем е-поште
  • displayLabel -- прилагођена ознака
  • displayName -- име за приказ
  • websiteUrl -- URL веб-сајта
  • groupIds -- чланства у групама
  • isAdmin -- администраторска права
  • isModerator -- права модератора
  • isProfileActivityPrivate -- приватност активности профила

Коментари у нитима Internal Link

Основна употреба

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)
СтилИзглед
._0Дугмад са стрелицама горе/доле са нето резултатом
._1Једно дугме у облику срца са бројем

Повратни позиви догађаја

Користите повратне позиве у облику модификатора за обраду интеракција са корисником:

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  // Најрелевантније


Разговор уживо Internal Link

LiveChatView пружа разговор у реалном времену са аутоматским скроловањем, раздвајачима датума и компактним изгледом. Аутоматски конфигурише SDK за сортирање са најстаријим прво и тренутни приказ уживо.

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 -- покреће се када је корисничко име или аватар додирнут(и)

Друштвени фид Internal Link


Систем за фид је посебан SDK (FastCommentsFeedSDK) са сопственим приказом.

Учитавање и приказивање фида

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.loadIfNeeded()
            }
    }
}

Приказ фида аутоматски укључује повуци‑за‑освежавање и бесконачно скроловање.
Користите loadIfNeeded() за поновни улаз у животни циклус екрана тако да постојећи или обновљени фид не ресетује на страницу 1.

Креирање постова

Користите FeedPostCreateView за приказ форме за креирање поста:

@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
        }
    )
}

Реаговање на постове

SDK управља реакцијама са оптимистичким ажурирањима:

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)

Отварање коментара на посту

Користите CommentsSheet за приказ коментара за пост у фиду. Он унутар креира FastCommentsSDK инстанцу користећи конфигурацију feed SDK‑а:

.sheet(item: $commentsPost) { post in
    CommentsSheet(post: post, feedSDK: sdk, onUserClick: { context, userInfo, source in
        // Обради клик корисника
    })
}

Напомена: FeedPost мора да имплементира Identifiable за .sheet(item:). Додајте ову екстензију:

extension FeedPost: @retroactive Identifiable {}

Филтрирање фида по ознакама

Имплементирајте протокол TagSupplier за филтрирање постова у фиду по ознакама:

struct TeamTagSupplier: TagSupplier {
    func getTags(currentUser: UserSessionInfo?) -> [String]? {
        guard let user = currentUser else { return nil }
        return ["team:\(user.id ?? "")", "public"]
    }
}

sdk.tagSupplier = TeamTagSupplier()

Вратите nil за нефилтрирани глобални фид.

Чување и враћање стања фида

Сачувајте стање пагинације током догађаја животног циклуса приказа:

let state = sdk.savePaginationState()
// Later...
sdk.restorePaginationState(state)
try? await sdk.loadIfNeeded()

Ако ваш екран привремено нестане, приказ фида аутоматски паузира живе ажурирања и наставља их по поновном појављивању без брисања учитаних постова. Позовите sdk.cleanup() само када заиста завршите са SDK инстанцом.

Брисање постова

sdk.onPostDeleted = { postId in
    print("Post \(postId) was deleted")
}

Прилагођавање тема Internal Link

Унапред дефинисане теме

Доступне су четири уграђене преднаподешене теме:

// Системске подразумеване вредности
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         // Еластична анимација при променама гласа

Примена тема

Два приступа:

// Via SwiftUI environment (recommended for view hierarchy)
FastCommentsView(sdk: sdk)
    .fastCommentsTheme(theme)

// Directly on the SDK
sdk.theme = theme

Прилагођена дугмадa на траци са алаткама Internal Link

Дугмад траке за коментаре

Имплементирајте протокол 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: { }
)

Или их поставите глобално на feed SDK:

sdk.globalFeedToolbarButtons = [HashtagButton()]

Модерација Internal Link

Радње доступне свим корисницима

  • Flag/Unflag -- пријавите коментар за преглед
try await sdk.flagComment(commentId: commentId)
try await sdk.unflagComment(commentId: commentId)
  • Block/Unblock -- сакријте све коментаре од корисника (по гледаоцу)
try await sdk.blockUser(commentId: commentId)
try await sdk.unblockUser(commentId: commentId)

Радње само за администраторе

  • Pin/Unpin -- закачи коментар на врх нити
try await sdk.pinComment(commentId: commentId)
try await sdk.unpinComment(commentId: commentId)
  • Lock/Unlock -- спречите нове одговоре на коментар, и блокирајте измене и брисања док се не откључа (важи за све, укључујући модераторе)
try await sdk.lockComment(commentId: commentId)
try await sdk.unlockComment(commentId: commentId)

Све модераторске радње су такође доступне преко контекстног менија коментара у корисничком интерфејсу. Администраторске радње се појављују само када је тренутни корисник администратор сајта (подешено преко SSO isAdmin заставице или конфигурације контролне табле).

Ажурирања у реалном времену Internal Link

Након позива sdk.load(), SDK аутоматски се претплаћује на WebSocket догађаје за конфигурисани urlId. Обрађују се следећи догађаји:

  • Нови коментари, измене и брисања
  • Гласови (нови и повучени)
  • Промене стања приквачења (pin), закључавања, означавања (flag) и блокирања
  • Присутност корисника (придруживање/напуштање)
  • Отварање/затварање нити
  • Доделе значки
  • Ажурирања конфигурације сервера

Контрола приказа уживо

Подразумевано, нови коментари других корисника се појављују одмах:

sdk.showLiveRightAway = true   // Подразумевано: приказати одмах

Поставите ово на false да бисте баферовали нове коментаре иза дугмета "N нових коментара", омогућавајући кориснику да изабере када да их прикаже:

sdk.showLiveRightAway = false

Присутност корисника

Индикатори онлајн/офлајн се аутоматски појављују на аватарима корисника када сервер омогући праћење присутности. На клијенту није потребна додатна конфигурација.



Пагинација Internal Link

Величина странице

// Коментари: подразумевано 30
sdk.pageSize = 50

// Фид: подразумевано 10
feedSDK.pageSize = 20

Учитавање више коментара

Корисничко сучеље аутоматски приказује контроле пагинације. Такође можете покренути пагинацију програмски:

// Учитај следећу страницу
try await sdk.loadMore()

// Учитај све преостале (онемогућено ако има >2000 коментара због перформанси)
try await sdk.loadAll()

// Провери стање
sdk.hasMore            // Да ли постоје још странице
sdk.shouldShowLoadAll()
sdk.getCountRemainingToShow()

Пагинација подкоментара

Угнеждени одговори се учитавају лениво. Када корисник прошири тему, првих 5 подкоментара се учитава. Појављује се контрола „учитај још одговора“ ако их има више. Ово се аутоматски обрађује у корисничком сучељу.

Стање и посматљивост Internal Link

Oba FastCommentsSDK и FastCommentsFeedSDK су класе ObservableObject са @Published својствима. Можете их посматрати у својим SwiftUI приказима за реактивна ажурирања корисничког интерфејса.

Objavljena svojstva FastCommentsSDK

PropertyTypeDescription
commentCountOnServerIntUkupan broj komentara na serveru
newRootCommentCountIntPrivremeno sačuvani novi komentari (kada је showLiveRightAway false)
currentUserUserSessionInfo?Trenutno autentifikovani korisnik
isSiteAdminBoolDa li је trenutni korisnik administrator sajta
isClosedBoolDa li је nit komentara zatvorena
hasBillingIssueBoolDa li постоји problem са наплатом
isLoadingBoolДа ли је мрежни захтев у току
hasMoreBoolДа ли постоје још странице са коментарима
blockingErrorMessageString?Грешка која спречава функционисање корисничког интерфејса
warningMessageString?Неблокирајућа порука упозорења
isDemoBoolДа ли се покреће у демо режиму
commentsVisibleBoolПрекидач за видљивост коментара
toolbarEnabledBoolДа ли је алатна трака за форматирање приказана

Objavljena svojstva FastCommentsFeedSDK

PropertyTypeDescription
feedPosts[FeedPost]Тренутно учитане објаве фида
hasMoreBoolДа ли постоје још странице
currentUserUserSessionInfo?Тренутно аутентификовани корисник
blockingErrorMessageString?Блокирајућа порука о грешци
isLoadingBoolДа ли је мрежни захтев у току
newPostsCountIntБрој нових објава од последњег учитавања

Stablo komentara

Stablo komentara je dostupno preko sdk.commentsTree:

// Ravna lista vidljivih čvorova za renderovanje
sdk.commentsTree.visibleNodes

// Pronađi komentar po ID-u
sdk.commentsTree.commentsById["comment-id"]

ЕУ регион Internal Link


Да бисте користили ЕУ центар података, подесите поље region у вашој конфигурацији:

let config = FastCommentsWidgetConfig(
    tenantId: "YOUR_TENANT_ID",
    urlId: "my-page",
    region: "eu"
)

Ово усмерава све API захтеве и WebSocket везе на eu.fastcomments.com.



Чишћење Internal Link

Када завршите са инстанцом SDK-а (нпр. када се поглед затвара), позовите cleanup() да бисте затворили WebSocket везу и отказали позадинске задатке:

sdk.cleanup()

За погледе које управља SwiftUI-јев @StateObject, ово се обично позива у .onDisappear или када се поглед уништи.

Отпремање слика Internal Link

Коментари

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")
])


Помене корисника Internal Link

Претрага корисника за подршку аутоматском довршавању @помена:

let results = try await sdk.searchUsers(query: "jan")
// Враћа [UserSearchResult] са userId, username, avatar итд.

Уграђени CommentInputBar аутоматски обрађује довршавање @помена.

Уређивање и брисање коментара Internal Link


Измени

try await sdk.editComment(commentId: commentId, newText: "Updated text")

Сервер поново рендерује HTML. Локални коментар се аутоматски ажурира.

Обриши

try await sdk.deleteComment(commentId: commentId)

Брисање коментара такође уклања његове потомке из локалног стабла.

Обе радње су доступне преко контекстног менија коментара у корисничком интерфејсу када је тренутни корисник аутор коментара (или администратор сајта).



Руковање грешкама Internal Link

Методе 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, које уграђени прикази показују кориснику.



Локализација Internal Link


Проследите код локала у конфигурацији да бисте локализовали стрингове које обезбеђује сервер:

let config = FastCommentsWidgetConfig(
    tenantId: "YOUR_TENANT_ID",
    urlId: "my-page",
    locale: "fr_fr"
)

Стрингови корисничког интерфејса на клијентској страни користе iOS пакетно базирану локализацију.



Пример апликације Internal Link


Репозиторијум садржи потпуни пример апликације у ExampleApp/ са демонстрацијама следећег:

  • Коментари у нитима са SSO и прилагођеним темама
  • Друштвени фид са креирањем објава и филтрирањем по ознакама
  • Разговор уживо
  • Једноставни и безбедни SSO токови
  • Прилагођена дугмад на траци са алаткама (коментари и фид)

Потребна помоћ?

Ако наиђете на било какве проблеме или имате питања у вези са iOS библиотеком, молимо вас:

Допринес

Доприноси су добродошли! Молимо вас да посетите GitHub репозиторијум за смернице за допринос.