Merge branch 'ios-opentok' into 'development'

Ios opentok

See merge request Cloud_Solution/doctor_app_flutter!144
merge-requests/145/head
Mohammad Aljammal 6 years ago
commit c8f558d50f

@ -13,7 +13,7 @@
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AF260AD724A4922F006461D3 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF260AD624A4922F006461D3 /* ViewController.swift */; };
9CE61EBD24AB366E008D68DD /* ViewControlleraa.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE61EBC24AB366E008D68DD /* ViewControlleraa.swift */; };
B650DC3076E9D70CB188286A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 93A5F83B23AB032D1E096663 /* Pods_Runner.framework */; };
/* End PBXBuildFile section */
@ -46,8 +46,8 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
9CE61EBC24AB366E008D68DD /* ViewControlleraa.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewControlleraa.swift; sourceTree = "<group>"; };
9D4B7DB43C6A6C849D2387CE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
AF260AD624A4922F006461D3 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ViewController.swift; path = ../../../../AndroidStudioProjects/open_tok_app/ios/Runner/ViewController.swift; sourceTree = "<group>"; };
E698D7B14B12DF768FE47A1A /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -106,7 +106,6 @@
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
AF260AD624A4922F006461D3 /* ViewController.swift */,
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
@ -116,6 +115,7 @@
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
9CE61EBC24AB366E008D68DD /* ViewControlleraa.swift */,
);
path = Runner;
sourceTree = "<group>";
@ -281,8 +281,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
AF260AD724A4922F006461D3 /* ViewController.swift in Sources */,
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
9CE61EBD24AB366E008D68DD /* ViewControlleraa.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

@ -91,7 +91,7 @@
<state key="normal" title="Button" image="muteButton"/>
<state key="selected" image="muteButtonSelected"/>
<connections>
<action selector="didClickMuteButton:" destination="t2c-G5-7AE" eventType="touchUpInside" id="xYM-PE-Zzq"/>
<action selector="didClickMuteButton:" destination="t2c-G5-7AE" eventType="touchUpInside" id="7lr-uj-db1"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ygd-al-G4F" userLabel="switchCameraButton">

@ -0,0 +1,330 @@
//
// ViewController.swift
// Runner
//
// Created by Mohammad Aljammal & Elham Rababah on 23/6/20.
// Copyright © 2020 The Chromium Authors. All rights reserved.
//
import UIKit
import OpenTok
class ViewController: UIViewController {
var session: OTSession?
var publisher: OTPublisher?
var subscriber: OTSubscriber?
var kApiKey:String = ""
var kSessionId:String = ""
var kToken:String = ""
override func viewDidLoad() {
super.viewDidLoad()
setupButtons()
askForMicrophonePermission()
requestCameraPermissionsIfNeeded()
hideVideoMuted()
setupSession()
// Do any additional setup after loading the view.
}
func setupButtons() {
perform(#selector(hideControlButtons), with: nil, afterDelay: 3)
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:)))
view.addGestureRecognizer(tapGestureRecognizer)
view.isUserInteractionEnabled = true
}
// MARK: -Microphone Camera and Permission Request
func askForMicrophonePermission() {
switch AVAudioSession.sharedInstance().recordPermission {
case AVAudioSession.RecordPermission.granted:
break
case AVAudioSession.RecordPermission.denied:
break
case AVAudioSession.RecordPermission.undetermined:
// This is the initial state before a user has made any choice
// You can use this spot to request permission here if you want
AVAudioSession.sharedInstance().requestRecordPermission({ granted in
// Check for granted
})
default:
break
}
}
func notifyUserOfCameraAccessDenial() {
// display a useful message asking the user to grant permissions from within Settings > Privacy > Camera
}
@IBAction func didClickMuteButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
publisher!.publishAudio = !sender.isSelected
}
@IBAction func didClickSpeakerButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
subscriber?.subscribeToAudio = !sender.isSelected
// resetHideButtonsTimer()
}
@IBAction func didClickVideoMuteButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
if publisher!.publishVideo {
publisher!.publishVideo = false
} else {
publisher!.publishVideo = true
}
localVideo.isHidden = sender.isSelected
localVideoMutedBg.isHidden = !sender.isSelected
localVideoMutedIndicator.isHidden = !sender.isSelected
// resetHideButtonsTimer()
}
@IBAction func didClickSwitchCameraButton(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
if sender.isSelected {
publisher!.cameraPosition = AVCaptureDevice.Position.front
} else {
publisher!.cameraPosition = AVCaptureDevice.Position.back
}
/// resetHideButtonsTimer()
}
@IBAction func hangUp(_ sender: UIButton) {
sessionDisconnect()
}
func sessionDisconnect() {
if (session != nil) {
print("disconnecting....")
session!.disconnect(nil)
dismiss(animated: true)
return
}
dismiss(animated: true)
}
// Converted to Swift 5.2 by Swiftify v5.2.26743 - https://swiftify.com/
func requestCameraPermissionsIfNeeded() {
// check camera authorization status
let authStatus: AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
switch authStatus {
case .authorized: break
// camera authorized
// do camera intensive stuff
case .notDetermined:
// request authorization
AVCaptureDevice.requestAccess(for: .video, completionHandler: { granted in
DispatchQueue.main.async(execute: {
if granted {
// do camera intensive stuff
} else {
self.notifyUserOfCameraAccessDenial()
}
})
})
case .restricted, .denied:
DispatchQueue.main.async(execute: {
self.notifyUserOfCameraAccessDenial()
})
default:
break
}
}
func hideVideoMuted() {
remoteVideoMutedIndicator.isHidden = true
localVideoMutedBg.isHidden = true
localVideoMutedIndicator.isHidden = true
}
func setupSession() {
//setup one time session
if (session != nil) {
session = nil
}
session = OTSession(
apiKey: kApiKey,
sessionId: kSessionId,
delegate: self)
var error: OTError?
session!.connect(withToken: kToken,error: &error)
}
func connectToAnOpenTokSession() {
session = OTSession(apiKey: kApiKey, sessionId: kSessionId, delegate: self)
var error: OTError?
session?.connect(withToken: kToken, error: &error)
if error != nil {
print(error!)
}
}
func showAlert(_ string: String?) {
// show alertview on main UI
DispatchQueue.main.async(execute: {
let alertVC = UIAlertController(
title: "OTError",
message: string,
preferredStyle: .alert)
self.present(alertVC, animated: true)
})
}
@IBOutlet weak var localVideo: UIView!
@IBOutlet weak var remoteVideo: UIView!
@IBOutlet weak var controlButtons: UIView!
@IBOutlet weak var remoteVideoMutedIndicator: UIImageView!
@IBOutlet weak var localVideoMutedBg: UIImageView!
@IBOutlet weak var localVideoMutedIndicator: UIImageView!
}
extension ViewController: OTSessionDelegate {
func sessionDidConnect(_ session: OTSession) {
print("The client connected to the OpenTok session.")
setupPublisher()
}
func setupPublisher() {
let settings = OTPublisherSettings()
settings.name = UIDevice.current.name
publisher = OTPublisher(delegate: self, settings: settings)
var error: OTError? = nil
session!.publish(publisher!, error: &error)
if error != nil {
showAlert(error?.localizedDescription)
}
publisher?.view!.frame = CGRect(x: localVideo.bounds.origin.x, y: localVideo.bounds.origin.y, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height)
localVideo.addSubview((publisher?.view)!)
}
func sessionDidDisconnect(_ session: OTSession) {
print("The client disconnected from the OpenTok session.")
}
func session(_ session: OTSession, didFailWithError error: OTError) {
print("The client failed to connect to the OpenTok session: \(error).")
}
func session(
_ session: OTSession,
connectionDestroyed connection: OTConnection
) {
if subscriber?.stream!.connection.connectionId == connection.connectionId {
cleanupSubscriber()
}
sessionDisconnect()
}
func session(_ session: OTSession, streamCreated stream: OTStream) {
subscriber = OTSubscriber(stream: stream, delegate: self)
guard let subscriber = subscriber else {
return
}
var error: OTError?
session.subscribe(subscriber, error: &error)
guard error == nil else {
print(error!)
return
}
guard let subscriberView = subscriber.view else {
return
}
subscriberView.frame = UIScreen.main.bounds
view.insertSubview(subscriberView, at: 0)
// if nil == subscriber {
// setupSubscribe(stream)
// }
}
func setupSubscribe(_ stream: OTStream?) {
subscriber = OTSubscriber(stream: stream!, delegate: self)
var error: OTError? = nil
session!.subscribe(subscriber!, error: &error)
if error != nil {
showAlert(error!.localizedDescription)
}
}
func session(_ session: OTSession, streamDestroyed stream: OTStream) {
if subscriber?.stream?.streamId == stream.streamId {
cleanupSubscriber()
}
print("A stream was destroyed in the session.")
}
func cleanupSubscriber() {
subscriber?.view!.removeFromSuperview()
subscriber = nil
}
}
extension ViewController: OTPublisherDelegate {
func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
print("The publisher failed: \(error)")
}
@objc func remoteVideoTapped(_ recognizer: UITapGestureRecognizer?) {
if controlButtons.isHidden {
controlButtons.isHidden = false
perform(#selector(hideControlButtons), with: nil, afterDelay: 3)
}
}
}
extension ViewController: OTSubscriberDelegate {
public func subscriberDidConnect(toStream subscriber: OTSubscriberKit) {
print("The subscriber did connect to the stream.")
}
public func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) {
print("The subscriber failed to connect to the stream.")
}
@objc func hideControlButtons() {
controlButtons.isHidden = true
}
}

@ -127,13 +127,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "7.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
charcode:
dependency: transitive
description:
@ -162,13 +155,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
code_builder:
dependency: transitive
description:
@ -260,13 +246,6 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "4.1.4"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
fixnum:
dependency: transitive
description:
@ -371,6 +350,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
image:
dependency: transitive
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
imei_plugin:
dependency: "direct main"
description:
@ -482,7 +468,7 @@ packages:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.6.4"
pedantic:
dependency: transitive
description:
@ -511,6 +497,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
platform:
dependency: transitive
description:
@ -683,7 +676,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.16"
version: "0.2.15"
timing:
dependency: transitive
description:
@ -747,6 +740,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
yaml:
dependency: transitive
description:
@ -755,5 +755,5 @@ packages:
source: hosted
version: "2.2.1"
sdks:
dart: ">=2.9.0-14.0.dev <3.0.0"
dart: ">=2.7.0 <3.0.0"
flutter: ">=1.12.13+hotfix.5 <2.0.0"

Loading…
Cancel
Save