aircore logo symbol
aircore logo

    Start Here

    What is Aircore?

    Authentication

    Channels

  • SDKs

    SDKs

    • Sync Audio

      iOS

      Quickstart
      Customization
      Samples
      Download SDK
      API Reference

      Android

      (Compose)

      Quickstart
      Sample
      Download SDK
      API Reference

      Android

      (View)

      Quickstart
      Sample
      Download SDK
      API Reference

      Web

      Quickstart
      Samples
      Download SDK
      API Reference

      Flex Audio

      iOS

      Quickstart
      More Options
      Sample
      Download SDK
      API Reference

      Android

      Quickstart
      Download SDK
      API Reference

Flex Audio SDK for iOS: Quickstart

The Aircore Flex Audio SDK for iOS allows you to quickly add high-quality, real-time voice chat to your iOS app. This lets you avoid dealing with the complexities of building a real-time system on your own.

This guide provides a basic pathway for adding the Flex Audio SDK to an iOS app.

Before starting

Minimum versions

  • Xcode: 13.2.1

  • iOS: 13.0

Limitations

  • For M1 and M2 Macs, you must run Xcode using Rosetta.

  • As of Xcode 14, bitcode is deprecated. With older versions of Xcode, turn off bitcode in your project's build settings to use this SDK.

Install the SDK

  1. Open the Xcode workspace for your app.

  2. Click File, then click Add Packages.

  3. Copy and paste this URL into the search bar:

    https://github.com/aircoreio/aircore-media-ios
    
  4. Select the Up to Next Major Version dependency rule.

  5. Click Add Package.

    Adding Flex iOS in Xcode.

  6. If you see the Choose Package Products dialog, click Add Package.

    Choose Package Products dialog in Xcode.

Xcode automatically links the framework to your project.

Set up your app

Enable background audio

We recommend adding the "Audio" and "Voice Over IP" background modes to your application's project settings. For more details, see Enabling Background Audio in Apple's documentation.

Configure the engine

Engine.sharedInstance is the central location for configuring this SDK.

Set up the engine once per launch, before you use the framework:

  1. To set the user agent, call the setUserAgent() method. This allows for better server-side logging and client information tracking.

  2. To set the log directory, call the setLogDirPath() method. You can send logs to us for troubleshooting.

Authenticate

In this guide, we use a publishable API key for a quick setup. To get your API key:

  1. Create an app in the Developer Console.

  2. Copy your publishable API key and use it to create channels in the next section.

Copying a publishable API key from the console.

For an overview of API keys, see Authentication. To use a secret API key with this SDK, see More Options.

Create and use a channel

A channel is a connection to a real-time session with other users. See Channels for a general overview.

Joining a channel allows your app to:

  • Publish a local stream, which is audio shared to other users

  • Receive remote streams, which are audio shared from other users

Create a channel

Engine.sharedInstance is a singleton that produces a channel object.

To start using a channel:

  1. Call the createChannel() method and keep the resulting channel object:

    import AircoreMedia
    
    let key = "PUBLISHABLE_API_KEY"
    
    // Keep this object around!
    let channel = Engine.sharedInstance.createChannel(
      publishableAPIKey: key,
      userID: "user_id",
      channelID: "channel_id"
    )
    // Check if the channel was successfully created
    guard let channel = channel else { fatalError() } // Handle error case
    
    // Store the channel somewhere safe
    channelStorage.channel = channel
    
  2. To connect to the channel and start receiving audio, call its join() method:

    channelStorage.channel.join()
    
  3. To set the volume for the channel, change the outputVolume property. You can set this before or after joining.

Leave a channel

When you no longer need a channel, call its leave() method. You can use leave() before local or remote users join.

Leaving destroys all objects for local and remote streams, releasing system resources used by the channel.

The local channel instance also terminates in these cases:

  • all references to the channel go out of scope

  • an unrecoverable error occurs

You cannot rejoin a terminated channel. To return to the session with the same users, create a new channel.

Track the status of a channel

The joinState property shows a channel's connection status.

To track changes to this property, use the joinStateDidChange notification:

let channel: Channel

NotificationCenter.default.addObserver(self,
selector: #selector(onChannelJoinStateChange(_:)),
name: ChannelNotification.joinStateDidChange, object: channel)

@objc func onChannelJoinStateChange(_ notif: NSNotification) {
// Get the join state from the notification and respond accordingly
guard let state = notif.userInfo?[ChannelNotification.Key.newJoinState] as?
   Channel.JoinState else { return }
switch state {
   case .notJoined:
      // The initial state. The channel has not yet connected.
      // No interaction with other users is possible.
      // NOTE: A notification for .notJoined is not sent.
   case .joining:
      // The channel is connecting for the first time.
   case .joined:
      // The channel is connected and automatically plays remote streams.
   case .rejoining:
      // The channel connected and then disconnected.
      // It is now reconnecting.
   case .terminated:
      // The channel has permanently disconnected. You can check the
      // termination cause here.
      // NOTE: You can't reuse the channel, but you can detect if the channel
      // terminated unexpectedly and either create a new channel or show an
      // error to the user.
      let terminationCause = channel.terminationCause
}
}

You can use the join state to build your user experience and UI:

  • In the .notJoined state, you can let the user join the channel. Or, you can have your app automatically join the channel.

  • In the .joined and .rejoining states, you can let the user publish a local stream. Or, you can have your app automatically publish a local stream.

  • In the .joining, .joined, and .rejoining states, you can let the user leave the channel.

  • In the .terminated state, you can show the user that the channel is disconnected. You can also let the user create a new channel.

Publish a local stream

Users share audio within a channel as streams. To publish audio to other users, you create a local stream.

  1. Use a channel's createLocalStream() method to create a local stream.

    The channel's join state must be .joined or .rejoining.

    import AircoreMedia
    
    // ... Create and join a channel
    
    // Make sure the channel is connected
    let channelJoinState = channel.joinState
    guard channelJoinState == .joined || channelJoinState == .rejoining else { return }
    
    // Default parameters
    let params = LocalStreamParams()
    
    let localStream = channel.createLocalStream(params: params)
    guard let localStream = localStream else { fatalError() } // Handle error case
    
  2. Use start() to publish audio from the microphone:

    // Start the local stream
    localStream.start()
    
    // You can choose to keep the local stream or access it from the channel
    
  3. Use muteAudio() to stop capturing and publishing audio:

    // Mute the audio
    localStream.muteAudio(true)
    
    // Unmute the audio
    localStream.muteAudio(false)
    

    To create a muted stream, see More Options.

  4. Stop the stream:

    // To stop sending local audio, stop the local stream
    localStream.stop()
    

Note: For local streams, muting and unmuting are asynchronous operations. If a channel does not have the allowPublishAudio permission, unmuting fails.

Get notifications for local streams

The LocalStreamNotification interface has notifications for mute state, voice activity, and connection state for local streams.

Receive remote streams

After you connect to a channel, your app begins receiving and playing audio published by other users. A RemoteStream object represents each incoming audio stream from another user.

The Flex Audio SDK receives audio and automatically plays it out through the active output device.

Check remote streams in a channel

To see all active remote streams within a channel, check its remoteStreams property. You can use this property to show active streams to the user.

To get notifications for added and removed streams, see More Options.

Check the connection to a remote stream

To see if a remote stream is connected, check the connectionState property.

To get notifications for remote stream connection status, see More Options.

Mute a remote stream

To mute a remote stream, use its muteAudio() method. When you locally mute a stream, the app still receives the audio but does not play it.

You can check local muting using:

  • The localAudioMuteStateDidChange notification

  • The localAudioMuted property

The publisher can also mute a stream. You can check remote muting with:

  • The remoteAudioMuteStateDidChange notification

  • The remoteAudioMuted property

Check for voice activity

To check if a remote stream has audible speech, use the voiceActivity property.

The voiceActivityStateDidChange notification shows changes to this property.

Check termination cause

To see why a remote stream ended, check the terminationCause property.

Terminated streams are removed from the channel's remoteStreams set and destroyed when your app no longer holds a reference to them.

More info

  • To continue building your app, see More Options.

  • See the full API reference.

  • Download our sample app.

  • on this page
  • Flex Audio SDK for iOS: Quickstart

  • Before starting

  • Install the SDK

  • Set up your app

  • Authenticate

  • Create and use a channel

  • Publish a local stream

  • Receive remote streams

  • More info