nimeet Docs
中文

iOS SDK Guide

Install, join a channel, publish/subscribe, screen sharing and permission notes.

Interface sections generated from the public SDK definitions

Version v1.1.0 · Updated 2026-10-26 · revision 1

The iOS surface is a native engine with Objective-C selector shapes: an AgoraRtcEngineKit singleton plus AgoraRtcEngineDelegate callbacks. Method names match the frozen Agora iOS SDK reference version symbol by symbol (the SDK interface definition; for apiVersion see "Platform and public interface definition" on this page).

Prerequisites

  • Xcode 16+, an iOS 15+ deployment target, Swift 5.9+ (Objective-C is supported too).
  • Info.plist must contain NSCameraUsageDescription and NSMicrophoneUsageDescription, otherwise the system rejects capture outright (with no prompt).
  • Screen sharing needs a separate Broadcast Upload Extension (ReplayKit) with an App Group configured.
  • You already have an appId and a token service (see Enable services and get credentials).

Install

ruby
# Podfile (planned coordinate; not yet published to the public CocoaPods codebase)
pod 'NimeetRtc', :path => '../sdk/ios'

Swift Package and Carthage forms will be published together in the release notes.

Get a token

The client must not hold customerSecret. The recommended setup has the host app's own backend issue tokens, injected through the callback form of RtcTokenProvider (the same concept as on Android):

swift
let provider = FallbackTokenProvider(providers: [
    CallbackTokenProvider { channel, uid, role, completion in
        authClient.fetchRtcToken(channel: channel, uid: uid, role: role, completion: completion)
    },
    StaticTokenProvider(token: ProcessInfo.processInfo.environment["NIMEET_TEST_TOKEN"] ?? "")
])

Join a channel

swift
import NimeetRtc

final class MeetingController: NSObject, AgoraRtcEngineDelegate {
    private var engine: AgoraRtcEngineKit?

    func start(appId: String, token: String, localView: UIView) {
        let config = AgoraRtcEngineConfig()
        config.appId = appId
        engine = AgoraRtcEngineKit.sharedEngine(withAppId: appId, delegate: self)
        engine?.setChannelProfile(.liveBroadcasting)
        engine?.enableVideo()
        let canvas = AgoraRtcVideoCanvas()
        canvas.view = localView
        engine?.setupLocalVideo(canvas)
        engine?.startPreview()

        let options = AgoraRtcChannelMediaOptions()
        options.clientRoleType = .broadcaster
        engine?.joinChannel(byToken: token,
                            channelId: "weekly-sync",
                            uid: 10001,
                            mediaOptions: options,
                            joinSuccess: { channel, uid, elapsed in
            print("joined \(channel) uid=\(uid) elapsed=\(elapsed)")
        })
    }

    func rtcEngine(_ engine: AgoraRtcEngineKit, didJoinedOfUid uid: UInt, elapsed: Int) {
        // A remote user joined: allocate the remote video container
    }

    func rtcEngine(_ engine: AgoraRtcEngineKit, didOfflineOfUid uid: UInt, reason: AgoraUserOfflineReason) {
        // A remote user left
    }

    func rtcEngine(_ engine: AgoraRtcEngineKit, didOccurError errorCode: AgoraErrorCode) {
        // Route by error number; see the error handling section
    }
}

Publish and subscribe

The native surface has no publish(track): AgoraRtcChannelMediaOptions decides what is published when joining, and switches control it afterwards.

swift
engine?.muteLocalAudioStream(true)        // mute the microphone
engine?.muteLocalVideoStream(true)        // turn off the camera video
engine?.updateChannelMediaOptions(options) // switch roles / change the subscription scope

Screen sharing uses ReplayKit: the host app starts a Broadcast Upload Extension, and the extension calls startScreenCapture: to feed sample buffers to the SDK.

Events

CallbackWhen it firesTypical handling
rtcEngine:didJoinedOfUid:elapsed:A remote user joinedAllocate a container
rtcEngine:firstRemoteVideoDecodedOfUid:size:elapsed:The first remote frame was decodedRender
rtcEngine:didOfflineOfUid:reason:A remote user leftRelease the container
rtcEngine:didOccurError:A runtime errorRoute by AgoraErrorCode
Token will-expire callbackBefore the privilege expiresRenew, then renewToken:

Error handling

  • Synchronous methods return Int32: 0 means success, and a negative value is an Agora error number.
  • Asynchronous errors go through didOccurError.
  • Unimplemented capabilities return -4 (ERR_NOT_SUPPORTED) and fail explicitly.

Troubleshooting

SymptomCauseHandling
Turning on the camera does nothingA usage description is missing from Info.plistAdd NSCameraUsageDescription / NSMicrophoneUsageDescription
Black screen on a physical device but fine in the simulatorThe simulator has no cameraVerify the capture path on a physical device
Joining failsThe token does not match the appId/channelSelf-check with GET /v1/tokens/verify
Screen sharing shows no videoThe extension has no App Group configuredCheck the extension's NSExtension configuration and the shared container
Media stops in the backgroundiOS suspends the appUse ReplayKit, or a foreground audio-session keep-alive strategy

Next steps

Platform information

Itemvalue
PlatformiOS
LanguageSwift / Objective-C
SDK packageNimeetRtc
Interface version4.7.0
Compatible Agora APIAgora ios API

The public interfaces are aligned with the Agora ios API; installation and runtime requirements are listed under Prerequisites above.

Availability

This platform's SDK: Generally available. The examples use the public API; runtime capability follows the published SDK package.

join-channel flow

The method names, parameter types and return values match the API reference for the same platform. Where a method has several overloads, the most common one is shown here; see the API reference for all overloads.

StepInterfaceMethodOverload count
enable video and local previewAgoraRtcEngineKitenableVideo1
Join a channelAgoraRtcEngineKitjoinChannelByToken:channelId:info:uid:joinSuccess:1
Leave a channelAgoraRtcEngineKitleaveChannel:1
Create instance / initializeAgoraRtcEngineKitsharedEngineWithAppId:delegate:1
typescript
enableVideo(): int
joinChannelByToken:channelId:info:uid:joinSuccess:(token?: NSString*, channelId: NSString*, info?: NSString*, uid: NSUInteger, joinSuccessBlock?: void(^ )(NSString*channel,NSUInteger uid,NSInteger elapsed)): int
leaveChannel:(leaveChannelBlock?: void(^ )(AgoraChannelStats*stat)): int
sharedEngineWithAppId:delegate:(appId: NSString*, delegate?: id): instancetype

Events and callbacks

This SDK has no event callbacks.

Error codes

Constantvalue
AgoraErrorCodeAdmGeneralError1005
AgoraErrorCodeAdmInitLoopback1022
AgoraErrorCodeAdmInitPlayout1008
AgoraErrorCodeAdmInitRecording1011
AgoraErrorCodeAdmJavaResource1006
AgoraErrorCodeAdmNoPlayoutDevice1360
AgoraErrorCodeAdmNoRecordingDevice1359
AgoraErrorCodeAdmPlayAbnormalFrequency1020
AgoraErrorCodeAdmRecordAbnormalFrequency1021
AgoraErrorCodeAdmRecordAudioFailed1018
AgoraErrorCodeAdmRuntimePlayoutError1015
AgoraErrorCodeAdmRuntimeRecordingError1017
AgoraErrorCodeAdmSampleRate1007
AgoraErrorCodeAdmStartLoopback1023
AgoraErrorCodeAdmStartPlayout1009
AgoraErrorCodeAdmStartRecording1012
AgoraErrorCodeAdmStopPlayout1010
AgoraErrorCodeAdmStopRecording1013
AgoraErrorCodeAlreadyInUse19
AgoraErrorCodeBitrateLimit115
AgoraErrorCodeBufferTooSmall6
AgoraErrorCodeConnectionInterrupted111
AgoraErrorCodeConnectionLost112
AgoraErrorCodeDecryptionFailed120
AgoraErrorCodeEncryptedStreamNotAllowedPublish130
AgoraErrorCodeFailed1
AgoraErrorCodeInitNetEngine21
AgoraErrorCodeInvalidAppId101
AgoraErrorCodeInvalidArgument2
AgoraErrorCodeInvalidChannelId102
AgoraErrorCodeInvalidState8
AgoraErrorCodeInvalidToken110
AgoraErrorCodeInvalidUserAccount134
AgoraErrorCodeJoinChannelRejected17
AgoraErrorCodeLeaveChannelRejected18
AgoraErrorCodeLoadMediaEngine1001
AgoraErrorCodeNoError0
AgoraErrorCodeNoServerResources103
AgoraErrorCodeNotInChannel113
AgoraErrorCodeNotInitialized7
AgoraErrorCodeNotReady3
AgoraErrorCodeNotSupported4
AgoraErrorCodePcmSendBufferOverflow201
AgoraErrorCodePcmSendFormat200
AgoraErrorCodeResourceLimited22
AgoraErrorCodeSizeTooLarge114
AgoraErrorCodeStartCall1002
AgoraErrorCodeStartCamera1003
AgoraErrorCodeStartVideoRender1004
AgoraErrorCodeTimedOut10
AgoraErrorCodeTokenExpired109
AgoraErrorCodeTooManyDataStreams116
AgoraErrorCodeVcmEncoderEncodeError1602
AgoraErrorCodeVcmEncoderInitError1601
AgoraErrorCodeVcmEncoderSetError1603
AgoraErrorCodeVcmUnknownError1600
AgoraErrorCodeVdmCameraNotAuthorized1501
AgoraErrorCodeVideoEffectAssetInvalid1700
AgoraErrorCodeVideoEffectEngineInvalid1702
AgoraErrorCodeVideoEffectInvalidBundlePath1707
AgoraErrorCodeVideoEffectInvalidParam1705
AgoraErrorCodeVideoEffectNodeNotActive1704
AgoraErrorCodeVideoEffectNotSupported1706
AgoraErrorCodeVideoEffectSaveFailed1701
AgoraErrorCodeWatermarkAGRB128
AgoraErrorCodeWatermarkInfo127
AgoraErrorCodeWatermarkParam124
AgoraErrorCodeWatermarkPath125
AgoraErrorCodeWatermarkPng126
AgoraErrorCodeWatermarkRead129

the platform REST layer uses REST error codes;the SDK layer maps connection/authentication failures to Agora error numbers, for the mapping table see SDK error identifiers per platform。

Generated by the documentation build pipeline · 2026-10-31 01:24:02 UTC · Documentation center v1.1.0.

Content follows the public API definitions.

ni-meet is a self-hosted RTC PaaS with a LiveKit-based media plane (Apache-2.0) and an Agora-compatible API.