# Implement features This section demonstrates how to make the buttons interactive by adding functions that enable the **Join Meeting** and **Start a Meeting** features. You will enable these features by using the **MeetingService** interface provided by Zoom Meeting SDK. ## Join a meeting The **Join a Meeting** feature of this demo app should allow a participant to join an existing meeting once they enter the **Meeting Number** and **Meeting Passcode** for the meeting.
In **ViewController.m** add a **joinMeeting** function that accepts meeting number and meeting passcode as parameters and passes the parameters to **joinMeetingWithJoinParam** method.
ViewController.m ```objectivec - (void)joinMeeting:(NSString *)meetingNumber meetingPassword:(NSString *)meetingPassword { // Get MobileRTCMeetingService instance from sharedRTC MobileRTCMeetingService *meetService = [[MobileRTC sharedRTC] getMeetingService]; if (meetService) { // Create a joinParams object from the MobileRTCMeetingJoinParam class to provide the MobileRTCMeetingService with the necessary info (Meeting Number and Meeting Passcode) to join a meeting. MobileRTCMeetingJoinParam *joinParams = [[MobileRTCMeetingJoinParam alloc] init]; joinParams.meetingNumber = meetingNumber; joinParams.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. [meetService joinMeetingWithJoinParam:joinParams]; } } ```In **ViewController.m**, add a **joinMeeting** function that accepts meeting number and meeting passcode as parameters and passes the parameters to **joinMeetingWithJoinParam** function using the **MobileRTCJoinParam** class.
ViewController.swift ```swift 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() { // 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) } } ``` ## Handle meeting callbacks**MobileRTCMeetingServiceDelegate** is a protocol implemented in the Zoom SDK to handle meeting events. To update **ViewController.m** to handle some of the events, you first need to set the `ViewController` as the delegate of the `MobileRTCMeetingServiceDelegate` instance. To do so, first, change the interface declaration in **ViewController.h** to conform to the **Meeting Service** delegate as follows:
ViewController.h ```objectivec #importNext, in **ViewController.m**, make the following changes to handle the events: 1. Add `meetService.delegate = self;` line inside the `if(meetingService)` conditional within the `joinMeeting` Method. 2. Use the delegate methods to listen for updates from the SDK about meeting connections and meeting states.
ViewController.m ```objectivec - (void)joinMeeting:(NSString *)meetingNumber meetingPassword:(NSString *)meetingPassword { // Obtain the MobileRTCMeetingService from the Zoom SDK, this service can start meetings, join meetings, leave meetings, etc. MobileRTCMeetingService *meetService = [[MobileRTC sharedRTC] getMeetingService]; if (meetService) { // Set the ViewContoller to be the MobileRTCMeetingServiceDelegate meetService.delegate = self MobileRTCMeetingJoinParam *joinParams = [[MobileRTCMeetingJoinParam alloc] init]; joinParams.meetingNumber = meetingNumber; joinParams.password = meetingPassword; [meetService joinMeetingWithJoinParam:joinParams]; } } /** MobileRTCMeetingServiceDelegate provides methods that listen for updates about meetings, such as meeting state changes, join attempt status, meeting errors, etc. **/ #pragma mark - MobileRTCMeetingServiceDelegate - (void)onMeetingError:(MobileRTCMeetError)error message:(NSString *)message { switch (error) { case MobileRTCMeetError_PasswordError: NSLog(@"Could not join or start meeting because the meeting password was incorrect."); default: NSLog(@"Could not join or start meeting with MobileRTCMeetError: %u %@", error, message); } } - (void)onJoinMeetingConfirmed { NSLog(@"Join meeting confirmed."); } - (void)onMeetingStateChange:(MobileRTCMeetingState)state { NSLog(@"Current meeting state: %u", state); } @end ```**MobileRTCMeetingServiceDelegate** is a protocol used by the Zoom SDK to handle meeting events. To update **ViewController.swift** to handle some of the events, you first need to set the `ViewController` as the delegate of the `MobileRTCMeetingServiceDelegate` instance. To do so, make the following changes in **ViewController.swift**: - Extend the **ViewController** class to adopt and conform to **MobileRTCMeetingServiceDelegate**. - Assign the **ViewController** as the **meetingServiceDelegate**.
ViewController.swift ```swift func joinMeeting(meetingNumber: String, meetingPassword: String) { if let meetingService = MobileRTC.shared().getMeetingService() { // 2. Set the ViewContoller to be the MobileRTCMeetingServiceDelegate meetingService.delegate = self let joinMeetingParameters = MobileRTCMeetingJoinParam() joinMeetingParameters.meetingNumber = meetingNumber joinMeetingParameters.password = meetingPassword meetingService.joinMeeting(with: joinMeetingParameters) } } // 1. Extend the ViewController class to adopt and conform to MobileRTCMeetingServiceDelegate. The delegate methods will listen for updates from the SDK about meeting connections and meeting states. 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)") } } ``` ## Start a meeting with ZAK When a user clicks the **Start an Instant Meeting** button, your app will attempt to start an instant meeting using the user info provided in your implementation. This includes the user Zoom Access Key (ZAK) token.To include this feature, implement the **startMeetingZak** function in the **ViewController.swift** file.
ViewController.swift ```swift func startMeetingZak() { if let meetingService = MobileRTC.shared().getMeetingService() { meetingService.delegate = self let startMeetingParams = MobileRTCMeetingStartParam4WithoutLoginUser() startMeetingParams.zak = "" // TODO: Enter ZAK startMeetingParams.userID = "" // TODO: Enter userID startMeetingParams.userName = "" // TODO: Enter your name meetingService.startMeeting(with: startMeetingParams) } } ``` ## Create alerts and handle user inputsUse **Alert View** to provide interfaces for users to enter meeting details **(meeting number and meeting passcode)**. Call the **presentJoinMeetingAlert** function inside the action you created, so that the alert is displayed when the user clicks the "**Join a Meeting**" button.
```swift @IBAction func joinAMeetingButtonPressed(_ sender: Any) { // Call the function to display the alert when the Join a Meeting button is pressed. presentJoinMeetingAlert() } // Function to create an alert dialog where users can enter meeting details. 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) } ```This is what your final **ViewController.swift** file should look like:
ViewController.swift ```swift 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) } // MARK: - IBOutlets @IBAction func joinAMeetingButtonPressed(_ sender: Any) { presentJoinMeetingAlert() } @IBAction func startAnInstantMeetingButtonPressed(_ sender: Any) { startMeetingZak() } // 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 initialized 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 ViewController 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) } } func startMeetingZak() { if let meetingService = MobileRTC.shared().getMeetingService() { meetingService.delegate = self let startMeetingParams = MobileRTCMeetingStartParam4WithoutLoginUser() startMeetingParams.zak = "" // TODO: Enter ZAK startMeetingParams.userID = "" // TODO: Enter userID startMeetingParams.userName = "" // TODO: Enter your name meetingService.startMeeting(with: startMeetingParams) } } // MARK: - Convenience Alerts /// Creates alert for prompting the user to enter a meeting number and passcode 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) } } // 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?) { print("Meeting error: \(error), message: \(String(describing: 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)") } } ```This is what your final **AppDelegate.swift** file should look like:
AppDelegate.swift ```swift import UIKit import MobileRTC @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { // Do not hard code JWT or any other confidential credentials in your production app. // Generate the JWT where you can securely store your Video SDK credentials, such as through a backend (server-side) function let jwt = "" var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { setupZoomSDK(token: jwt) return true } // Logs the user out of the app upon application termination. // This is not a necessary 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() // Notify MobileRTC of appWillTerminate call. MobileRTC.shared().appWillTerminate() } } func applicationWillResignActive(_ application: UIApplication) { // Notify MobileRTC of appWillResignActive call. MobileRTC.shared().appWillResignActive() } func applicationDidBecomeActive(_ application: UIApplication) { // Notify MobileRTC of appDidBecomeActive call. MobileRTC.shared().appDidBecomeActive() } func applicationDidEnterBackground(_ application: UIApplication) { // Notify MobileRTC of appDidEnterBackgroud call. MobileRTC.shared().appDidEnterBackgroud() } /* Creates, Initializes, 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. Do not hard code JWT or any other confidential credentials in your production app. - Parameters: - token: Zoom Meeting SDKs use JWT for authorization. Generate it using your app credentials. */ func setupSDK(token: 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 use 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 isSDKInitialized= = MobileRTC.shared().initialize(context) // Check if initialization was successful. Obtain a MobileRTCAuthService, this is for supplying credentials to the SDK for authorization. if isSDKInitialized == true, let authorizationService = MobileRTC.shared().getAuthService() { // Supply the SDK with jwt. authorizationService.jwtToken = token // 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 .success: print("SDK successfully initialized.") case .keyOrSecretEmpty: assertionFailure("SDK Key/Secret was not provided. Replace sdkKey and sdkSecret at the top of this file with your SDK Key/Secret.") case .keyOrSecretWrong, .unknown: assertionFailure("SDK Key/Secret is not valid.") default: assertionFailure("SDK Authorization failed with MobileRTCAuthError: \(returnValue).") } } } ``` ## Run your app Connect your iOS device and press **Run** in Xcode to run your app in your device. Press the **Join Meeting** button to join a meeting as a participant or press the **Start Meeting** button to start an instant meeting. Once you enter the meeting, you can see the Zoom UI and functionalities integrated in your app. ## Next steps This was a simple quickstart made to get you up and running with the Meeting SDK. Next, check out the sample apps included in your downloaded SDK package and read the SDK docs to understand and implement advanced features. ```