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', '~> 2.0.1'
Requirements: iOS 15.1+, arm64. In Info.plist add:
NSCameraUsageDescription, required for the live-camera path.ITSAppUsesNonExemptEncryptionset toNO. 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.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.
App and screen lifecycle
App backgrounding is handled automatically. The SDK stops live moderation and releases its visual model resources. The next startStream, analyzeImage or analyzeVideo call reloads them automatically.
When the app remains active but the moderation screen is closed or hidden, suspend its visual resources explicitly:
NosmaiSDK.suspendVisualModeration()
Stop your AVCaptureSession at the same time. Text moderation remains ready and does not need to be initialized again.
Thresholds
NosmaiSDK.setNsfwThreshold(.explicit, value: 0.45) // BLOCK NosmaiSDK.setNsfwThreshold(.sexy, value: 0.55) // WARN
Cleanup
NosmaiSDK.shutdown()
[!NOTE]
analyzeImageandmoderateTextare synchronous and fast, but they still run inference, so call them off the main thread.analyzeVideois async with a completion handler.