Skip to content

Commit d06c86c

Browse files
authored
Release 3.8.0 (#55)
* Release 3.8.0 * Add note about meeting only SDK in podfile * Bump up testflight version and make miniumum deployment target as iOS 11
1 parent d8010bb commit d06c86c

29 files changed

+1133
-294
lines changed

KitchenSink.xcodeproj/project.pbxproj

Lines changed: 99 additions & 71 deletions
Large diffs are not rendered by default.

KitchenSink/AppDelegate.swift

Lines changed: 127 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,17 @@ var incomingCallData: [Meeting] = [] // have to keep this in centralised place
3030
@UIApplicationMain
3131
class AppDelegate: UIResponder, UIApplicationDelegate {
3232
var window: UIWindow?
33-
33+
var callKitManager: CallKitManager?
34+
class var shared: AppDelegate {
35+
return UIApplication.shared.delegate as! AppDelegate
36+
}
3437
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
3538
window = UIWindow()
3639
navigateToLoginViewController()
3740
window?.makeKeyAndVisible()
38-
41+
if (callKitManager == nil) {
42+
callKitManager = CallKitManager()
43+
}
3944
UNUserNotificationCenter.current().requestAuthorization(options: [.sound, .alert, .badge]) { granted, error in
4045
if granted {
4146
print("Approval granted to send notifications")
@@ -46,7 +51,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
4651
application.registerForRemoteNotifications()
4752
self.voipRegistration()
4853
UNUserNotificationCenter.current().delegate = self
49-
5054
return true
5155
}
5256

@@ -60,24 +64,57 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
6064
}
6165

6266
func navigateToLoginViewController() {
63-
window?.rootViewController = LoginViewController()
67+
if !(UIApplication.shared.topViewController() is CallViewController) {
68+
window?.rootViewController = LoginViewController()
69+
}
6470
}
6571

6672
// Register for VoIP notifications
6773
func voipRegistration() {
6874
// Create a push registry object
69-
let mainQueue = DispatchQueue.main
70-
let voipRegistry = PKPushRegistry(queue: mainQueue)
71-
voipRegistry.delegate = self
72-
voipRegistry.desiredPushTypes = [PKPushType.voIP]
75+
let voipRegistry = PKPushRegistry(queue: .main)
76+
voipRegistry.delegate = self
77+
voipRegistry.desiredPushTypes = [PKPushType.voIP]
7378
}
7479
}
75-
80+
7681
extension AppDelegate: UNUserNotificationCenterDelegate {
7782
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
7883
completionHandler(.alert)
7984
}
8085

86+
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
87+
guard let authType = UserDefaults.standard.string(forKey: "loginType") else { return }
88+
if authType == "jwt" {
89+
initWebexUsingJWT()
90+
} else if authType == "token" {
91+
initWebexUsingToken()
92+
} else {
93+
initWebexUsingOauth()
94+
}
95+
DispatchQueue.main.async {
96+
webex.initialize { success in
97+
if success {
98+
do {
99+
let data = try JSONSerialization.data(withJSONObject: userInfo, options: .prettyPrinted)
100+
let string = String(data: data, encoding: .utf8) ?? ""
101+
print("Received push: string")
102+
print(string)
103+
webex.phone.processPushNotification(message: string) { error in
104+
if let error = error {
105+
print("processPushNotification error" + error.localizedDescription)
106+
}
107+
}
108+
}
109+
catch (let error){
110+
print(error.localizedDescription)
111+
}
112+
113+
}
114+
}
115+
}
116+
}
117+
81118
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
82119
guard let handler = window?.rootViewController as? PushNotificationHandler else {
83120
print("RootViewController must confirm to a PushNotificationHandler")
@@ -135,4 +172,85 @@ extension AppDelegate: PKPushRegistryDelegate {
135172
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
136173
print("pushRegistry:didInvalidatePushTokenForType:\(type)")
137174
}
175+
176+
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
177+
debugPrint("Received push: voIP")
178+
debugPrint(payload.dictionaryPayload)
179+
180+
if type == .voIP {
181+
// Report the call to CallKit, and let it display the call UI.
182+
guard let bsft = payload.dictionaryPayload["bsft"] as? [String: Any], let sender = bsft["sender"] as? String else {
183+
print("payload not valid")
184+
return
185+
}
186+
187+
callKitManager?.reportIncomingCallFor(uuid: UUID(), sender: sender) {
188+
completion()
189+
self.establishConnection(payload: payload)
190+
}
191+
}
192+
}
193+
194+
func establishConnection(payload: PKPushPayload) {
195+
guard let authType = UserDefaults.standard.string(forKey: "loginType") else { return }
196+
if authType == "jwt" {
197+
initWebexUsingJWT()
198+
} else if authType == "token" {
199+
initWebexUsingToken()
200+
} else {
201+
initWebexUsingOauth()
202+
}
203+
DispatchQueue.main.async {
204+
webex.initialize { [weak self] success in
205+
if success {
206+
webex.phone.onIncoming = { [weak self] call in
207+
self?.callKitManager?.updateCall(call: call)
208+
}
209+
do {
210+
let data = try JSONSerialization.data(withJSONObject: payload.dictionaryPayload, options: .prettyPrinted)
211+
let string = String(data: data, encoding: .utf8) ?? ""
212+
print("Received push: string")
213+
print(string)
214+
webex.phone.processPushNotification(message: string) { error in
215+
if let error = error {
216+
print("processPushNotification error" + error.localizedDescription)
217+
}
218+
}
219+
}
220+
catch (let error){
221+
print(error.localizedDescription)
222+
}
223+
224+
} else {
225+
print("Failed to initialise WebexSDK on receiving incoming call push notification")
226+
}
227+
}
228+
}
229+
}
230+
231+
func initWebexUsingOauth() {
232+
guard let path = Bundle.main.path(forResource: "Secrets", ofType: "plist") else { return }
233+
guard let keys = NSDictionary(contentsOfFile: path) else { return }
234+
let clientId = keys["clientId"] as? String ?? ""
235+
let clientSecret = keys["clientSecret"] as? String ?? ""
236+
let redirectUri = keys["redirectUri"] as? String ?? ""
237+
let scopes = "spark:all" // spark:all is always mandatory
238+
239+
// See if we already have an email stored in UserDefaults else get it from user and do new Login
240+
if let email = EmailAddress.fromString(UserDefaults.standard.value(forKey: "userEmail") as? String) {
241+
// The scope parameter can be a space separated list of scopes that you want your access token to possess
242+
let authenticator = OAuthAuthenticator(clientId: clientId, clientSecret: clientSecret, scope: scopes, redirectUri: redirectUri, emailId: email.toString())
243+
webex = Webex(authenticator: authenticator)
244+
return
245+
}
246+
}
247+
248+
func initWebexUsingJWT() {
249+
webex = Webex(authenticator: JWTAuthenticator())
250+
}
251+
252+
func initWebexUsingToken() {
253+
webex = Webex(authenticator: TokenAuthenticator())
254+
}
138255
}
256+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "missed-call.png",
5+
"idiom" : "universal",
6+
"scale" : "1x"
7+
},
8+
{
9+
"filename" : "missed-call@2x.png",
10+
"idiom" : "universal",
11+
"scale" : "2x"
12+
},
13+
{
14+
"filename" : "missed-call@3x.png",
15+
"idiom" : "universal",
16+
"scale" : "3x"
17+
}
18+
],
19+
"info" : {
20+
"author" : "xcode",
21+
"version" : 1
22+
}
23+
}
502 Bytes
Loading
1.05 KB
Loading
1.63 KB
Loading

0 commit comments

Comments
 (0)