Proper Documentation for ios Swift

Where can i find a proper documentation to implement zoom sdk for ios in Swift?
I tried searching but I can only find documentation and guides for objective C.

Hey @codelogicapp

Currently we only have documentation for Objective-C, we will let you know if that changes though! In the meantime I can help you with a Swift implementation if youd like?

Thanks!
Michael

Hello @Michael_Condon,
Yes it would be awesome if you could help us in the Swift implementation. I am looking forward for it.

Hey @codelogicapp

Awesome! Here is an example of an AppDelegate and ViewController that should help get you started. This example code uses interface builder for two buttons. The project setup and framework import will be about the same for Swift as it is in the docs: https://marketplace.zoom.us/docs/sdk/native-sdks/iOS/getting-started

ViewController.swift:

//
//  ViewController.swift
//  ZoomiOSSDKDemo
//
//  Created by Zoom Video Communications on 8/14/20.
//  Copyright Ā© 2020 Zoom Video Communications. All rights reserved.
//

import UIKit
import MobileRTC

class ViewController: UIViewController {

    // MARK: - LifeCycle

    override func viewDidLoad() {
        super.viewDidLoad()

        // The Zoom SDK requires a UINavigationController to update the UI for us. Here we supplied the SDK with the ViewControllers navigationController.
        MobileRTC.shared().setMobileRTCRootController(self.navigationController)

        /// Notification that is used to start a meeting upon log in success.
        NotificationCenter.default.addObserver(self, selector: #selector(userLoggedIn), name: NSNotification.Name(rawValue: "userLoggedIn"), object: nil)
    }

    // MARK: - IBOutlets

    @IBAction func joinAMeetingButtonPressed(_ sender: Any) {
        presentJoinMeetingAlert()
    }

    @IBAction func startAnInstantMeetingButtonPressed(_ sender: Any) {
        // Obtain the MobileRTCAuthService from the Zoom SDK, and check if the user is logged into Zoom.
        if let authorizationService = MobileRTC.shared().getAuthService(), authorizationService.isLoggedIn() {
            startMeeting()
        } else {
            presentLogInAlert()
        }
    }

    // MARK: - Zoom SDK Examples

    /// Puts user into ongoing Zoom meeting using a known meeting number and meeting password.
    ///
    /// Assign a MobileRTCMeetingServiceDelegate to listen to meeting events and join meeting status.
    ///
    /// - Parameters:
    ///   - meetingNumber: The meeting number of the desired meeting.
    ///   - meetingPassword: The meeting password of the desired meeting.
    /// - Precondition:
    ///   - Zoom SDK must be intitalized and authorized.
    ///   - MobileRTC.shared().setMobileRTCRootController() has been called.
    func joinMeeting(meetingNumber: String, meetingPassword: String) {
        // Obtain the MobileRTCMeetingService from the Zoom SDK, this service can start meetings, join meetings, leave meetings, etc.
        if let meetingService = MobileRTC.shared().getMeetingService() {

            // Set the ViewContoller to be the MobileRTCMeetingServiceDelegate
            meetingService.delegate = self

            // Create a MobileRTCMeetingJoinParam to provide the MobileRTCMeetingService with the necessary info to join a meeting.
            // In this case, we will only need to provide a meeting number and password.
            let joinMeetingParameters = MobileRTCMeetingJoinParam()
            joinMeetingParameters.meetingNumber = meetingNumber
            joinMeetingParameters.password = meetingPassword

            // Call the joinMeeting function in MobileRTCMeetingService. The Zoom SDK will handle the UI for you, unless told otherwise.
            // If the meeting number and meeting password are valid, the user will be put into the meeting. A waiting room UI will be presented or the meeting UI will be presented.
            meetingService.joinMeeting(with: joinMeetingParameters)
        }
    }

    /// Logs user into their Zoom account using the user's Zoom email and password.
    ///
    /// Assign a MobileRTCAuthDelegate to listen to authorization events including onMobileRTCLoginReturn(_ returnValue: Int).
    ///
    /// - Parameters:
    ///   - email: The user's email address attatched to their Zoom account.
    ///   - password: The user's password attatched to their Zoom account.
    /// - Precondition:
    ///   - Zoom SDK must be intitalized and authorized.
    func logIn(email: String, password: String) {
        // Obtain the MobileRTCAuthService from the Zoom SDK, this service can log in a Zoom user, log out a Zoom user, authorize the Zoom SDK etc.
        if let authorizationService = MobileRTC.shared().getAuthService() {
            // Call the login function in MobileRTCAuthService. This will attempt to log in the user.
            authorizationService.login(withEmail: email, password: password, rememberMe: false)
        }
    }

    /// Creates and starts a Zoom instant meeting. An instant meeting is an unscheduled meeting that begins instantly.
    ///
    /// Assign a MobileRTCMeetingServiceDelegate to listen to meeting events and start meeting status.
    ///
    /// - Precondition:
    ///   - Zoom SDK must be intitalized and authorized.
    ///   - MobileRTC.shared().setMobileRTCRootController() has been called.
    ///   - User has logged into Zoom successfully.
    func startMeeting() {
        // Obtain the MobileRTCMeetingService from the Zoom SDK, this service can start meetings, join meetings, leave meetings, etc.
        if let meetingService = MobileRTC.shared().getMeetingService() {
            // Set the ViewContoller to be the MobileRTCMeetingServiceDelegate
            meetingService.delegate = self

            // Create a MobileRTCMeetingStartParam to provide the MobileRTCMeetingService with the necessary info to start an instant meeting.
            // In this case we will use MobileRTCMeetingStartParam4LoginlUser(), since the user has logged into Zoom.
            let startMeetingParameters = MobileRTCMeetingStartParam4LoginlUser()

            // Call the startMeeting function in MobileRTCMeetingService. The Zoom SDK will handle the UI for you, unless told otherwise.
            meetingService.startMeeting(with: startMeetingParameters)
        }
    }

    // MARK: - Convenience Alerts

    /// Creates alert for prompting the user to enter meeting number and password for joining a meeting.
    func presentJoinMeetingAlert() {
        let alertController = UIAlertController(title: "Join meeting", message: "", preferredStyle: .alert)

        alertController.addTextField { (textField : UITextField!) -> Void in
            textField.placeholder = "Meeting number"
            textField.keyboardType = .phonePad
        }
        alertController.addTextField { (textField : UITextField!) -> Void in
            textField.placeholder = "Meeting password"
            textField.keyboardType = .asciiCapable
            textField.isSecureTextEntry = true
        }

        let joinMeetingAction = UIAlertAction(title: "Join meeting", style: .default, handler: { alert -> Void in
            let numberTextField = alertController.textFields![0] as UITextField
            let passwordTextField = alertController.textFields![1] as UITextField

            if let meetingNumber = numberTextField.text, let password = passwordTextField.text {
                self.joinMeeting(meetingNumber: meetingNumber, meetingPassword: password)
            }
        })
        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: { (action : UIAlertAction!) -> Void in })

        alertController.addAction(joinMeetingAction)
        alertController.addAction(cancelAction)

        self.present(alertController, animated: true, completion: nil)
    }

    /// Creates alert for prompting the user to enter thier Zoom credentials for starting a meeting.
    func presentLogInAlert() {
        let alertController = UIAlertController(title: "Log in", message: "", preferredStyle: .alert)

        alertController.addTextField { (textField : UITextField!) -> Void in
            textField.placeholder = "Email"
            textField.keyboardType = .emailAddress
        }
        alertController.addTextField { (textField : UITextField!) -> Void in
            textField.placeholder = "Password"
            textField.keyboardType = .asciiCapable
            textField.isSecureTextEntry = true
        }

        let logInAction = UIAlertAction(title: "Log in", style: .default, handler: { alert -> Void in
            let emailTextField = alertController.textFields![0] as UITextField
            let passwordTextField = alertController.textFields![1] as UITextField

            if let email = emailTextField.text, let password = passwordTextField.text {
                self.logIn(email: email, password: password)
            }
        })
        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: { (action : UIAlertAction!) -> Void in })

        alertController.addAction(logInAction)
        alertController.addAction(cancelAction)

        self.present(alertController, animated: true, completion: nil)
    }

    // MARK: - Internal

    /// Selector that is used to start a meeting upon log in success.
    @objc func userLoggedIn() {
        startMeeting()
    }
}

// MARK: - MobileRTCMeetingServiceDelegate

// Conform ViewController to MobileRTCMeetingServiceDelegate.
// MobileRTCMeetingServiceDelegate listens to updates about meetings, such as meeting state changes, join attempt status, meeting errors, etc.
extension ViewController: MobileRTCMeetingServiceDelegate {

    // Is called upon in-meeting errors, join meeting errors, start meeting errors, meeting connection errors, etc.
    func onMeetingError(_ error: MobileRTCMeetError, message: String?) {
        switch error {
        case MobileRTCMeetError_PasswordError:
            print("Could not join or start meeting because the meeting password was incorrect.")
        default:
            print("Could not join or start meeting with MobileRTCMeetError: \(error) \(message ?? "")")
        }
    }

    // Is called when the user joins a meeting.
    func onJoinMeetingConfirmed() {
        print("Join meeting confirmed.")
    }

    // Is called upon meeting state changes.
    func onMeetingStateChange(_ state: MobileRTCMeetingState) {
        print("Current meeting state: \(state)")
    }
}

AppDelegate.swift:

//
//  AppDelegate.swift
//  ZoomiOSSDKDemo
//
//  Created by Zoom Video Communications on 8/14/20.
//  Copyright Ā© 2020 Zoom Video Communications. All rights reserved.
//

import UIKit
import MobileRTC

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    // Obtain your SDK Key and SDK Secret and paste it here.
    // Your SDK Secret should NEVER be publically accessible, only use the sdk key and secret for testing this demo app.
    // For your own application, you must obtain a JWT instead of using the SDK Key and SDK Secret.
    let sdkKey = ""
    let sdkSecret = ""

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        setupSDK(sdkKey: sdkKey, sdkSecret: sdkSecret)

        return true
    }

    // Logs the user out of the app upon application termination.
    // This is not a neccesary action. In real use cases, the SDK should be alerted of app events. For example, in applicationWillTerminate(_ application: UIApplication), MobileRTC.shared().appWillTerminate should be called.
    func applicationWillTerminate(_ application: UIApplication) {
        // Obtain the MobileRTCAuthService from the Zoom SDK, this service can log in a Zoom user, log out a Zoom user, authorize the Zoom SDK etc.
        if let authorizationService = MobileRTC.shared().getAuthService() {

            // Call logoutRTC() to log the user out. 
            authorizationService.logoutRTC()
        }
    }

    /// Creates, Intializes, and Authorizes an instance of the Zoom SDK. This must be called before any other SDK functions.
    ///
    /// Assign a MobileRTCAuthDelegate to listen to SDK authorization events.
    ///
    /// In real applications, SDK Key's and SDK Secret's should not be used as they are highly sensitive data. A JWT should be used instead.
    /// Do not leave a JWT, SDK Key, or SDK Secret anywhere that is not secured.
    ///
    /// - Parameters:
    ///   - sdkKey: A valid SDK Client Key provided by the Zoom Marketplace.
    ///   - sdkSecret: A valid SDK Client Secret provided by the Zoom Marketplace.
    func setupSDK(sdkKey: String, sdkSecret: String) {
        // Create a MobileRTCSDKInitContext. This class contains attributes for modifying how the SDK will be created. You must supply the context with a domain.
        let context = MobileRTCSDKInitContext()
        // The domain we will us is zoom.us
        context.domain = "zoom.us"
        // Turns on SDK logging. This is optional.
        context.enableLog = true

        // Call initialize(_ context: MobileRTCSDKInitContext) to create an instance of the Zoom SDK. Without initializing first, the SDK will not do anything. This call will return true if the SDK was initialized successfully.
        let sdkInitializedSuccessfully = MobileRTC.shared().initialize(context)

        // Check if initializaiton was successful. Obtain a MobileRTCAuthService, this is for supplying credentials to the SDK for authorization.
        if sdkInitializedSuccessfully == true, let authorizationService = MobileRTC.shared().getAuthService() {

            // Supply the SDK with SDK Key and SDK Secret. This is required if a JWT is not supplied.
            // To use a JWT, replace these lines with authorizationService.jwtToken = yourJWTToken.
            authorizationService.clientKey = sdkKey
            authorizationService.clientSecret = sdkSecret

            // Assign AppDelegate to be a MobileRTCAuthDelegate to listen for authorization callbacks.
            authorizationService.delegate = self

            // Call sdkAuth to perform authorization.
            authorizationService.sdkAuth()
        }
    }
}

// MARK: - MobileRTCAuthDelegate

// Conform AppDelegate to MobileRTCAuthDelegate.
// MobileRTCAuthDelegate listens to authorization events like SDK authorization, user login, etc.
extension AppDelegate: MobileRTCAuthDelegate {

    // Result of calling sdkAuth(). MobileRTCAuthError_Success represents a successful authorization.
    func onMobileRTCAuthReturn(_ returnValue: MobileRTCAuthError) {
        switch returnValue {
        case MobileRTCAuthError_Success:
            print("SDK successfully initialized.")
        case MobileRTCAuthError_KeyOrSecretEmpty:
            assertionFailure("SDK Key/Secret was not provided. Relpace sdkKey and sdkSecret at the top of this file with your SDK Key/Secret.")
        case MobileRTCAuthError_KeyOrSecretWrong, MobileRTCAuthError_Unknown:
            assertionFailure("SDK Key/Secret is not valid.")
        default:
            assertionFailure("SDK Authorization failed with MobileRTCAuthError: \(returnValue).")
        }
    }

    // Result of calling logIn(). 0 represents a successful log in attempt.
    func onMobileRTCLoginReturn(_ returnValue: Int) {
        switch returnValue {
        case 0:
            print("Successfully logged in")

            // This alerts the ViewController that log in was successful. This is not a neccesary action.
            NotificationCenter.default.post(name: Notification.Name("userLoggedIn"), object: nil)
        case 1002:
            print("Password incorrect")
        default:
            print("Could not log in. Error code: \(returnValue)")
        }
    }

    // Result of calling logoutRTC(). 0 represents a successful log out attempt.
    func onMobileRTCLogoutReturn(_ returnValue: Int) {
        switch returnValue {
        case 0:
            print("Successfully logged out")
        default:
            print("Could not log out. Error code: \(returnValue)")
        }
    }
}

Let me know if that helps or if you have questions!
Michael

we will let you know if that changes though

Soā€¦you guys support Swift, but arenā€™t planning on documenting it?

Hey @GroovinChip,

Thanks for using the dev forum.

The documentation is currently being updated with Swift. https://marketplace.zoom.us/docs/sdk/native-sdks/iOS/build-an-app/implement-features
If you need any code snippets from Objective-C documentation in Swift, I would be happy to provide those here.

Thanks!
Michael

Hi Michael.

Yes, Iā€™m aware of that page. Do you know when the ā€œMastering Zoom SDKā€ pages will be updated to reflect Swift?

My particular needs are a little more complicated than simply using Swift over Objective-C, but I will be making a separate post to ask about that.

1 Like

Hey @GroovinChip,

I am not sure of a definitive date, but it will be very soon. Is there any part of that section that you need assistance with?

Thanks!
Michael

Not immediately, my first priority is SDK initialization and joining meetings unauthenticated, but thereā€™s a twist. Thatā€™s what I will be posting momentarily. Iā€™ll link it when Iā€™m done writing it.

@Michael_Condon posted: What is the correct method for implementing the iOS Swift SDK via a Flutter plugin?

@GroovinChip

Sounds good!

Michael

Hello, I am also looking for updates for this topic of documenting Zoom SDK development for Swift and not just Objective-C. There are a couple of helpful posts in the support forums from users, but Swift and Zoom have expanded in popularity in the past year and still it seems there is no mention from Zoom itself on when an update of ā€˜Mastering Zoom SDKā€™ documentation for swift will be available. Can you check on an update? ā€˜Very soonā€™ seems to have stretched to almost one yearā€¦ Iā€™m sure we would all really appreciate better docs to help enable devs to build apps using Zoom framework.

Thanks in advance.
Vince

Hey @vince80027,

Thank you for your concern. We do not yet have a timeline on when we will release documentation in swift. For now, please let me know if there are any features you would like swift samples for.

Thanks!
Michael

Thank you Michael, I appreciate the efforts of support staff on these forums to help devs out. Iā€™m currently working on trying to implement starting an instant meeting by email login on iOS 14.8 with swift using SDK zoom-sdk-ios-5.7.6.1080. I started with this post by @tspiresweet as a base SwiftUI and Zoom SDK - #10 by Michael_Condon and the SDK reports initializing successfully and am able to join meetings successfully. So looking for more information on what setup I need to do before I can login and then startMeeting. Currently:

func logIn(email: String, password: String) {
        print("DEBUG: login...")

        // 2. Obtain the MobileRTCAuthService from the Zoom SDK, this service can log in a Zoom user, log out a Zoom user, authorize the Zoom SDK etc.
        if let authorizationService = MobileRTC.shared().getAuthService() {
             // 3. Call the login function in MobileRTCAuthService. This will attempt to log in the user.
            authorizationService.login(withEmail: email, password: password, rememberMe: false)
            print("DEBUG: logged in =  \(authorizationService.isLoggedIn())")
        }else {
            print("authorization service failed")
        }
    }

getting logged in = false and a crash of EXC_BAD_ACCESS on the line marked as @main for my AppDelegate, which seemed to work fine in the anonymous joinMeeting function. I suspect I may have to restructure my swift application to use App type instead of what was originally developed in an older style with ContentView with an AppDelegate marked as @main and to implement the UIApplicationDelegateAdaptor - new topics for me to figure out - but to be clear more swift docs around starting an instant meeting is my ask here (as well as longer term ask of more comprehensive docs to make using zoom SDK within swift apps easier).

@main
class AppDelegate: UIResponder, UIApplicationDelegate { ā€¦ }

Hey @vince80027,

Where is the crash happening? Right after calling login?

Thanks!
Michael

Hello @Michael_Condon, I refactored my app to use the App style and got more familiar with SDK and the only time Iā€™m seeing a crash if if I enter a login account with an intentionally bad password via a swiftui .sheet and donā€™t dismiss it after failure and edit the password to the correct one and then attempt to start a meeting. Hereā€™s the log from my app:

DEBUG: connect to zoom - instant meeting
check video permissions
DEBUG: access granted for video stream
finding window to provide to zoom sdk
DEBUG: attempting login w/wait ...using [user creds omitted]
DEBUG: login...
DEBUG: wait 2 secs - was logged in
DEBUG: start meeting...
DEBUG: in meetingService....
DEBUG: meeting Params <MobileRTCMeetingStartParam4LoginlUser: 0x28036eb20>
DEBUG: called start meeting which returned with value = 0
onMeetingError : MobileRTCMeetError_Success
(lldb)

I have also seen some issues in initiating the Zoom meeting from a button on a sheet (and then dismissing the sheet as the meeting starts) will cause the app to crash when the meeting is ended.

Iā€™m also interested in a better way to wait on the login() function to return to launch startMeeting() - Iā€™ve tried several ways and currently using with a hacky 2 second wait before I check authorizationService.isLoggedIn() and start the meeting. Iā€™ve tried using dispatch groups and also tried to setup the NotificationCenter in the appDelegate to invoke a function on userLoggedIn event but I never see that activated in my app. Also, my AppDelegate extension of onMobileRTCLoginResult or onMobileRTCLoginReturn is not being called (is Result now the correct one to use?). I do see other calls happening for onMobileRTCAuthReturn indicating the SDK is initialized. I could continue that in a new thread if you wish. I can also use some help setting up JWTs correctly, Iā€™m using SDK key and secret currently and that is working fine.

@Michael_Condon - I see my issue with getting the login callback. It looks like the SDK changed the name as well as the method signature of the login callback from:

func onMobileRTCLoginReturn(_ returnValue: Int) {

to

func onMobileRTCLoginResult(_ resultValue: MobileRTCLoginFailReason) { 

and I had updated the name but not the params or case statement to use the new enum.

with that issue resolved, I am now getting the callback as expected - so I can get rid of the hacky timer and use the login success callback to trigger the meeting start.

Hey @vince80027,

Oh ok I see, so you are not facing any issues anymore?

Thanks!
Michael

Thanks for checking in @Michael_Condon, for login with email/password Iā€™m good now. Iā€™m looking for any examples of implementing screenShare with swift examples - can you provide any pointers there the docx file only seems to reference Objective-C? Also have some questions around the issue with annotations in screenshare - is there a doc/tech note that explains the right sequence to use to initiate a screen share in Meeting SDK without the annotations button being hidden and needing to be overridden? In the Zoom client app on IOS, annotations do not appear to work on iOS devices but do work on Mac desktop client - does that mean iOS SDK will or will not provide them?

Hey @vince80027,

Thanks for using the dev forum!

We have some examples of implementing screensharing with swift here: https://marketplace.zoom.us/docs/sdk/native-sdks/iOS/mastering-zoom-sdk/in-meeting-function/screen-share. There is a toggle above the code snippets to switch between objective-c and swift.

Annotations are indeed supported in both the client app and SDK, can you clarify what you mean by:

Thanks!
Michael

Thanks @Michael_Condon I will check out those examples of swift screenshare. I should clarify the issues I have been having with annotations: When using the Zoom client (and I presume the SDK) with ā€˜Share screenā€™ option - I cannot use annotations on iPad or MacOS desktop. From this link annotation for collaboration under iOS is noted ā€œYou cannot annotate when sharing your entire screen into the meeting via iOS device. You can only annotate when sharing a portion of your screen.ā€ I have not been able to find anyway to share/broadcast a portion of my screen, only the entire screen. I can use annotations from either zoom client or SDK created Meeting with the ā€˜Share Content/Photoā€™ using a screenshot Iā€™ve taken. Is there any way to get around this annotation issue with sharing the entire screen by sharing a subset of screen or some other technique (there was a reference to overriding a view hierarchy in this thread- which I would like some additional details on) you could share?

Thanks for the patient support and your time in educating newish zoom devs!

Vince