Skip to content

automat-berlin/afone

Repository files navigation

Automat

Release v1.3 Xcode 10.2+ Swift 5.0+ iOS 12.1+ CocoaPods Compatible License MIT Twitter AutomatBerlin

//afone is the reference implementation for SIP Telephony on iOS that can be used on different SIP stacks with no effort. It comes with an easily extensible adapters concept that encapsulates all details of various providers.

Requirements

  • Xcode 10.2+
  • Swift 5.0+
  • iOS 12.1+
  • CocoaPods 1.7.0+
  • SIP-based Server / Service Provider

Features

  • VoIP Adapter Reference Implementation
  • Voice & Video Calls
  • CallKit Integration
  • DTMF Support
  • Extensible Adapters Concept
  • Push Notifications (Local)
  • Background Connectivity
  • User-friendly Animations & Feedback
  • Brand / CI Customization
  • Contact list with search and index scrolling
  • Alternative App icon support
  • Dark mode support on iOS 13

Usage

Before you use the application, you have to look up your authentication credentials to a SIP-based server and make sure they are valid.

Login Screen

Enter your credentials (account, password, server). If your server uses a default configuration, you can log in right away.

Login Settings

In case you need to customize the application to your environment, tap Advanced and configure preferences like local & remote ports, transport protocols, STUN server, or TLS certificate validation.

Dialer

Enter a phone number and make a call. You can tap on delete to revert your input.

Dialer

You can also show your local contact list and have an easier way to call your friends and business contacts.

Call Screen

//afone’s call interface supports all standard features. While making a call you can mute it, put it on the speaker, switch to a video call and switch the device camera. You can also tap on the Keypad button to enter DTMF signals.

Adapter Settings

In the Settings screen you can configure audio & video codecs, SRTP. You can also log out. The application will let you log in again afterwards.

Adapter Settings

In the Settings screen under Appearance you can change the App icon. We provide three different app icons to chose from.

Installation

Dependencies

//afone uses CocoaPods as its dependency manager. For usage and installation instructions, visit their website. Before you open & build the project in Xcode, you have to install all dependencies first. Make sure CocoaPods is installed on your machine, then install all required project dependencies:

pod install

Build & Run

After you have installed all dependencies, just open the Xcode workspace. Select the desired simulator and run the project. If you want to run //afone on a device, you’ll have to configure signing in the Xcode Target preferences. Visit the official Apple documentation for more information about device provisioning.

Customization

If you want to further customize the application you can either extend the reference PortSIPAdapter implementation, or preferably write your own adapter that conforms to the VoIPManagerDelegate protocol (and eventually other protocols if they are required by the 3rd-party client libraries you use).

Configuration

Based on the configurations you provide, the application automatically creates a settings view that lets an user select supported preferences:

var audioCodecs: [Codec] { get }

Return supported audio codecs (e. g. G.729, PCMA, GSM, ILBC, SPEEX, OPUS).

var videoCodecs: [Codec] { get }

Return supported video codecs (e. g. H.263, H.264, VP8, VP9).

var srtpOptions: [SRTP] { get }

Return your supported SRTP options (e. g. none, prefer, force).

var localVideoView: UIView? { get }

Return your local video view here, which should be provided by your VoIP SDK.

var remoteVideoView: UIView? { get }

Return your remote video view here, which should be provided by your VoIP SDK.

var needsCodecs: Bool { get }

Indicate whether the user needs to choose audio codecs in order to make a call

Delegation

Implement the following delegate functions if you want to create your own adapter:

func answerCall(_ sessionId: Int, videoCall: Bool, completion: (NSError?) -> Void)
func hangUp(_ sessionId: Int, completion: (NSError?) -> Void)
func hold(_ sessionId: Int, completion: (NSError?) -> Void)
func unhold(_ sessionId: Int, completion: (NSError?) -> Void)
func mute(_ sessionId: Int, mute: Bool, completion: (NSError?) -> Void)
func rejectCall(_ sessionId: Int, code: Int, completion: (NSError?) -> Void)
func sendDTMF(_ sessionId: Int, character: Character)
func createCall(to: String, completion: (Call?, NSError?) -> Void)
func initAdapter(credentials: Credentials, completion: @escaping (NSError?) -> Void)
func didEnterBackground()

To save battery, you should suspend connection to your backend.

func willEnterForeground()

Reestablish connection to your backend here, to be able to receive and make calls.

func logout(completion: (() -> Void)?)
func cancelLogin()
func reload(with settings: Settings)
func startAudio()
func stopAudio()
func enableLocalVideo(_ enable: Bool, completion: ((Bool) -> Void)?)
func enableRemoteVideo(_ enable: Bool, completion: ((Bool) -> Void)?)
func toggleCameraPosition(completion: (NSError?) -> Void)

The function names represent common operations and should be self-explanatory. Depending on the backend you want to integrate, you either call other 3rd-party libraries, or implement your own communication & connection handling inside these functions. See PortSIPAdapter for a reference implementation.

Colors & Other Defaults

You can customize colors and other defaults of the application in Constants. The structure holds customization options for call defaults, SIP defaults, or the keychain key name.

FAQ

Why do you have dependencies? I thought a good library shouldn’t have dependencies?

While it is technically correct that a good library should stand for itself without requiring other dependencies, //afone isn’t a library, but a complete softphone reference implementation with a full-fledged application architecture, dependency management, custom view components, and much more. Most of this functionality is a core part of the main repository, but there is no point in reinventing the wheel and writing the n-th implementation of a logging library (where already great implementations exist). If you think the project should further minimize its dependencies, we welcome your contribution and a pull request.

Known Issues

The UI is not compatible with smaller displays (4", iPhone 5, iPhone 5s, iPhone SE).

Contribute

We welcome any contributions. Contact us if you have any questions.

Contact

//afone is owned and maintained by Automat Berlin GmbH.

Acknowledgements

Elevator Music by Kevin Macleod distributed under Attribution 3.0 Unported (CC BY 3.0)

License

//afone is released under the MIT license. See LICENSE for details.