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.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.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.