Docs / Nosmai Moderation / Platform guides / iOS

iOS

Use Nosmai Moderation in a native iOS (Swift) app: image, video, text and live-camera moderation.

Install

Install via CocoaPods. Add the pod to your Podfile and run pod install. The SDK and its bundled models come with the pod, and everything runs on-device with no external dependencies.

pod 'NosmaiModerationSDK', '~> 1.0'

Requirements: iOS 14+, arm64. In Info.plist add:

  • NSCameraUsageDescription, required for the live-camera path.
  • ITSAppUsesNonExemptEncryption set to NO. The SDK only encrypts its own bundled models locally, which is export-compliance exempt. Without this, every TestFlight or App Store upload stalls on the encryption question.

Initialize

initialize is blocking (network plus model load), so call it off the main thread. It returns false if the license is invalid or expired.

import NosmaiDetection

DispatchQueue.global(qos: .userInitiated).async {
    let ok = NosmaiSDK.initialize(licenseKey: "NOSMAI-XXXX")
}

Moderate an image

if let r = NosmaiSDK.analyzeImage(uiImage) {     // NosmaiResult?
    if r.isUnsafe {
        // r.detections -> [NosmaiObjectDetection], r.nsfw -> .safe / .warn / .block
    }
}

Moderate a video

NosmaiSDK.analyze(videoURL: url, frameIntervalMs: 500,
    progress: { p in /* 0...1 */ },
    completion: { result in /* result.isUnsafe, .categories, .flags */ })

Moderate text

Call initialize first, since it validates the license. initializeText needs that before it can load the text model.

try? NosmaiSDK.initializeText()                  // after initialize(), off the main thread
if let t = NosmaiSDK.moderateText("some message") {
    if t.blocked { /* t.layer, t.category, t.matchedWord */ }
}

Live camera (AVCaptureSession)

Feed pixel buffers from your AVCaptureVideoDataOutput to pushFrame. Results arrive via the NosmaiListener.

NosmaiSDK.startStream(listener: self)            // self conforms to NosmaiListener

// in captureOutput(_:didOutput:from:)
if let pb = CMSampleBufferGetImageBuffer(sampleBuffer) {
    NosmaiSDK.pushFrame(pb, rotationDegrees: 90)  // 90 makes a back-camera portrait buffer upright
}

// on leave
NosmaiSDK.stopStream()

Show the preview with an AVCaptureVideoPreviewLayer backed by the same AVCaptureSession.

Thresholds

NosmaiSDK.setThreshold(.weapon, value: 0.70)
NosmaiSDK.setNsfwThreshold(.explicit, value: 0.45)  // BLOCK
NosmaiSDK.setNsfwThreshold(.sexy, value: 0.55)      // WARN

Cleanup

NosmaiSDK.shutdown()

NOTE

analyzeImage and moderateText are synchronous and fast, but they still run inference, so call them off the main thread. analyzeVideo is async with a completion handler.

Nosmai

We make advanced camera and AI technology accessible to every developer. By packaging hard problems into simple

developers
legal
newsletter

Product updates and release notes. No spam.

© 2026 nosmai, inc · all rights reserved