Skip to content

Commit 2da5487

Browse files
author
Jaesung
authored
Merge pull request #73 from sendbird/release/1.3.0
Release/1.3.0
2 parents 128f04a + 5a3a20f commit 2da5487

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1544
-1131
lines changed

.swiftlint.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ disabled_rules: # rule identifiers to exclude from running
99
- xctfail_message
1010
- function_parameter_count
1111
- large_tuple
12+
- switch_case_alignment
13+
- valid_ibinspectable
1214
opt_in_rules: # some rules are only opt-in
1315
- implicit_return
1416
- explicit_self

QuickStart.xcodeproj/project.pbxproj

Lines changed: 90 additions & 15 deletions
Large diffs are not rendered by default.

QuickStart.xcodeproj/xcshareddata/xcschemes/QuickStart.xcscheme

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<BuildableReference
1616
BuildableIdentifier = "primary"
1717
BlueprintIdentifier = "A9A72CA02387B448007C0878"
18-
BuildableName = "SendBird Calls.app"
18+
BuildableName = "Sendbird Calls.app"
1919
BlueprintName = "QuickStart"
2020
ReferencedContainer = "container:QuickStart.xcodeproj">
2121
</BuildableReference>
@@ -45,7 +45,7 @@
4545
<BuildableReference
4646
BuildableIdentifier = "primary"
4747
BlueprintIdentifier = "A9A72CA02387B448007C0878"
48-
BuildableName = "SendBird Calls.app"
48+
BuildableName = "Sendbird Calls.app"
4949
BlueprintName = "QuickStart"
5050
ReferencedContainer = "container:QuickStart.xcodeproj">
5151
</BuildableReference>
@@ -62,7 +62,7 @@
6262
<BuildableReference
6363
BuildableIdentifier = "primary"
6464
BlueprintIdentifier = "A9A72CA02387B448007C0878"
65-
BuildableName = "SendBird Calls.app"
65+
BuildableName = "Sendbird Calls.app"
6666
BlueprintName = "QuickStart"
6767
ReferencedContainer = "container:QuickStart.xcodeproj">
6868
</BuildableReference>

QuickStart.xcodeproj/xcshareddata/xcschemes/QuickStartIntent.xcscheme

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<BuildableReference
3131
BuildableIdentifier = "primary"
3232
BlueprintIdentifier = "A9A72CA02387B448007C0878"
33-
BuildableName = "SendBird Calls.app"
33+
BuildableName = "Sendbird Calls.app"
3434
BlueprintName = "QuickStart"
3535
ReferencedContainer = "container:QuickStart.xcodeproj">
3636
</BuildableReference>
@@ -60,7 +60,7 @@
6060
<BuildableReference
6161
BuildableIdentifier = "primary"
6262
BlueprintIdentifier = "A9A72CA02387B448007C0878"
63-
BuildableName = "SendBird Calls.app"
63+
BuildableName = "Sendbird Calls.app"
6464
BlueprintName = "QuickStart"
6565
ReferencedContainer = "container:QuickStart.xcodeproj">
6666
</BuildableReference>
@@ -78,7 +78,7 @@
7878
<BuildableReference
7979
BuildableIdentifier = "primary"
8080
BlueprintIdentifier = "A9A72CA02387B448007C0878"
81-
BuildableName = "SendBird Calls.app"
81+
BuildableName = "Sendbird Calls.app"
8282
BlueprintName = "QuickStart"
8383
ReferencedContainer = "container:QuickStart.xcodeproj">
8484
</BuildableReference>

QuickStart/AppDelegate+Intent.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@ import UIKit
1010
import CallKit
1111
import SendBirdCalls
1212

13-
// This extension is for outgoing call from outside the app.
13+
// MARK: - From Native Call Logs
14+
// To make an outgoing call from native call logs, so called "Recents" in iPhone, you need to implement this method and add IntentExtension as a new target.
15+
// Please refer to IntentHandler (path: ~/QuickStartIntent/IntentHandler.swift)
16+
// (Optional) To make an outgoing call from url, you need to use `application(_:open:options:)` method. The implementation is very similar as `application(_:continue:restorationHandler:)
17+
1418
extension AppDelegate {
1519

16-
// MARK: - From Native Call Logs
17-
// To make an outgoing call from native call logs, so called "Recents" in iPhone, you need to implement this method and add IntentExtension as a new target.
18-
// Please refer to IntentHandler (path: ~/QuickStartIntent/IntentHandler.swift)
19-
// (Optional) To make an outgoing call from url, you need to use `application(_:open:options:)` method. The implementation is very similar as `application(_:continue:restorationHandler:)
20-
2120
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
2221
guard let dialParams = userActivity.dialParams else {
23-
UIApplication.shared.showError(with: "Could not determine dial params")
22+
UIApplication.shared.showError(with: DialErrors.getLogFailed.localizedDescription)
23+
2424
return false
2525
}
2626

QuickStart/AppDelegate+SendBirdCallsDelegates.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@ import UIKit
99
import CallKit
1010
import SendBirdCalls
1111

12-
// MARK: - SendBirdCalls Delegates
12+
// MARK: - Sendbird Calls Delegates
1313
extension AppDelegate: SendBirdCallDelegate, DirectCallDelegate {
1414
// MARK: SendBirdCallDelegate
15+
// Handles incoming call. Please refer to `AppDelegate+VoIP.swift` file
1516
func didStartRinging(_ call: DirectCall) {
1617
call.delegate = self // To receive call event through `DirectCallDelegate`
1718

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//
2+
// AppDelegate+SoundEffects.swift
3+
// QuickStart
4+
//
5+
// Created by Jaesung Lee on 2020/07/30.
6+
// Copyright © 2020 SendBird Inc. All rights reserved.
7+
//
8+
9+
import SendBirdCalls
10+
11+
// MARK: DirectCall sound effects
12+
// If you use CallKit framework, you have to set ringing sound by using `CXProviderConfiguration.ringtoneSound`. See `CXProvider+QuickStart.swift` file.
13+
// If you use CallKit framework, you must implement `CXProviderDelegate.provider(_:didActivate:)` and `CXProviderDelegate.provider(_:didDeactivate:)`
14+
extension AppDelegate {
15+
func addDirectCallSounds() {
16+
// SendBirdCall.setDirectCallSound("Ringing.mp3", forKey: .ringing)
17+
SendBirdCall.addDirectCallSound("Dialing.mp3", forType: .dialing)
18+
SendBirdCall.addDirectCallSound("ConnectionLost.mp3", forType: .reconnecting)
19+
SendBirdCall.addDirectCallSound("ConnectionRestored.mp3", forType: .reconnected)
20+
21+
// If you want to remove added DirectCall sounds,
22+
// Use `SendBirdCall.removeDirectCallSound(forType:)`
23+
}
24+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//
2+
// AppDelegate+URLScheme.swift
3+
// QuickStart
4+
//
5+
// Created by Jaesung Lee on 2020/09/18.
6+
// Copyright © 2020 SendBird Inc. All rights reserved.
7+
//
8+
9+
import UIKit
10+
11+
// MARK: - URL Scheme
12+
// Used URL scheme: sendbird
13+
// Following method tries to sign in with account information decoded from passed URL.
14+
// For more information about Custom URL Scheme for your app, see [Defining a Custom URL Scheme for Your App](https://developer.apple.com/documentation/xcode/allowing_apps_and_websites_to_link_to_your_content/defining_a_custom_url_scheme_for_your_app)
15+
16+
extension AppDelegate {
17+
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
18+
19+
// Authenticate only when there is no signed in account
20+
guard UserDefaults.standard.credential == nil else {
21+
UIApplication.shared.showError(with: CredentialErrors.alreadyAuthenticated.localizedDescription)
22+
return false
23+
}
24+
25+
// Get credential from the URL and authenticate
26+
do {
27+
let pendingCredential = try CredentialManager.shared.handle(url: url)
28+
self.authenticate(with: pendingCredential) { error in
29+
if let error = error {
30+
// Failed to authenticate
31+
UIApplication.shared.showError(with: error.localizedDescription)
32+
return
33+
}
34+
35+
guard let signInVC = self.window?.rootViewController?.presentedViewController else { return }
36+
signInVC.dismiss(animated: true, completion: nil)
37+
}
38+
} catch {
39+
// Failed to decode URL
40+
UIApplication.shared.showError(with: error.localizedDescription)
41+
return false
42+
}
43+
44+
return true
45+
}
46+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//
2+
// AppDelegate+VoIPPush.swift
3+
// QuickStart
4+
//
5+
// Created by Jaesung Lee on 2020/09/18.
6+
// Copyright © 2020 SendBird Inc. All rights reserved.
7+
//
8+
9+
import UIKit
10+
import CallKit
11+
import PushKit
12+
import SendBirdCalls
13+
14+
// MARK: VoIP Push
15+
extension AppDelegate: PKPushRegistryDelegate {
16+
func voipRegistration() {
17+
self.voipRegistry = PKPushRegistry(queue: DispatchQueue.main)
18+
self.voipRegistry?.delegate = self
19+
self.voipRegistry?.desiredPushTypes = [.voIP]
20+
}
21+
22+
// MARK: - SendBirdCalls - Registering push token.
23+
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
24+
UserDefaults.standard.voipPushToken = pushCredentials.token
25+
print("Push token is \(pushCredentials.token.toHexString())")
26+
27+
SendBirdCall.registerVoIPPush(token: pushCredentials.token, unique: true) { error in
28+
guard error == nil else { return }
29+
}
30+
}
31+
32+
// MARK: - SendBirdCalls - Receive incoming push event
33+
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
34+
SendBirdCall.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type, completionHandler: nil)
35+
}
36+
37+
// MARK: - SendBirdCalls - Handling incoming call
38+
// Please refer to `AppDelegate+SendBirdCallsDelegates.swift` file.
39+
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
40+
SendBirdCall.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type) { uuid in
41+
guard uuid != nil else {
42+
let update = CXCallUpdate()
43+
update.remoteHandle = CXHandle(type: .generic, value: "invalid")
44+
let randomUUID = UUID()
45+
46+
CXCallManager.shared.reportIncomingCall(with: randomUUID, update: update) { _ in
47+
CXCallManager.shared.endCall(for: randomUUID, endedAt: Date(), reason: .acceptFailed)
48+
}
49+
completion()
50+
return
51+
}
52+
53+
completion()
54+
}
55+
}
56+
}

QuickStart/AppDelegate.swift

Lines changed: 40 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ import UIKit
99
import CallKit
1010
import PushKit
1111
import SendBirdCalls
12-
import AVFoundation
12+
13+
var versionInfo: String {
14+
let sampleVersion = Bundle.main.version
15+
return "QuickStart \(sampleVersion) SDK \(SendBirdCall.sdkVersion)"
16+
}
1317

1418
@UIApplicationMain
1519
class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -23,21 +27,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
2327
// See [here](https://github.com/sendbird/quickstart-calls-ios#creating-a-sendbird-application) for the application ID.
2428
// SendBirdCall.configure(appId: YOUR_APP_ID)
2529

26-
if SendBirdCall.appId != nil {
27-
// User ID Mode
28-
self.window = UIWindow(frame: UIScreen.main.bounds)
29-
guard let window = self.window else { return false }
30-
window.rootViewController = UIStoryboard.signController()
31-
window.makeKeyAndVisible()
32-
} else if let appId = UserDefaults.standard.appId {
33-
// QR Code Mode
34-
SendBirdCall.configure(appId: appId)
30+
self.autoSignIn { error in
31+
if error == nil { return }
32+
// Show SignIn controller when failed to auto sign in
33+
self.window?.rootViewController?.present(UIStoryboard.signController(), animated: true, completion: nil)
3534
}
3635

3736
// To process incoming call, you need to add `SendBirdCallDelegate` and implement its protocol methods.
3837
SendBirdCall.addDelegate(self, identifier: "com.sendbird.calls.quickstart.delegate")
3938

39+
// To receive incoming call, you need to register VoIP push token
4040
self.voipRegistration()
41+
self.addDirectCallSounds()
4142

4243
return true
4344
}
@@ -64,52 +65,42 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
6465
// There might be some calls failed to be ended
6566
// In this case, I recommend that you register local notification to notify the unterminated calls.
6667
}
67-
}
68-
69-
extension AppDelegate: PKPushRegistryDelegate {
70-
func voipRegistration() {
71-
self.voipRegistry = PKPushRegistry(queue: DispatchQueue.main)
72-
self.voipRegistry?.delegate = self
73-
self.voipRegistry?.desiredPushTypes = [.voIP]
74-
}
75-
76-
func pushRegistry(_ registry: PKPushRegistry, didInvalidatePushTokenFor type: PKPushType) {
77-
//
78-
}
7968

80-
// MARK: SendBirdCalls - Registering push token.
81-
func pushRegistry(_ registry: PKPushRegistry, didUpdate pushCredentials: PKPushCredentials, for type: PKPushType) {
82-
UserDefaults.standard.voipPushToken = pushCredentials.token
83-
print("Push token is \(pushCredentials.token.toHexString())")
84-
85-
SendBirdCall.registerVoIPPush(token: pushCredentials.token, unique: true) { error in
86-
guard error == nil else { return }
87-
// Even if an error occurs, SendBirdCalls will save the pushToken value and reinvoke this method internally while authenticating.
69+
// MARK: - SendBirdCall - Auto Sign In
70+
func autoSignIn(completionHandler: @escaping (Error?) -> Void) {
71+
// fetch credential
72+
guard let pendingCredential = UserDefaults.standard.credential else {
73+
DispatchQueue.main.async {
74+
completionHandler(CredentialErrors.empty)
75+
}
76+
return
8877
}
78+
// authenticate
79+
self.authenticate(with: pendingCredential, completionHandler: completionHandler)
8980
}
9081

91-
// MARK: SendBirdCalls - Receive incoming push event
92-
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType) {
93-
SendBirdCall.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type, completionHandler: nil)
94-
}
95-
96-
// Handle Incoming pushes
97-
func pushRegistry(_ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type: PKPushType, completion: @escaping () -> Void) {
98-
// MARK: Handling incoming call
99-
SendBirdCall.pushRegistry(registry, didReceiveIncomingPushWith: payload, for: type) { uuid in
100-
guard uuid != nil else {
101-
let update = CXCallUpdate()
102-
update.remoteHandle = CXHandle(type: .generic, value: "invalid")
103-
let randomUUID = UUID()
104-
105-
CXCallManager.shared.reportIncomingCall(with: randomUUID, update: update) { _ in
106-
CXCallManager.shared.endCall(for: randomUUID, endedAt: Date(), reason: .acceptFailed)
82+
func authenticate(with credential: Credential, completionHandler: @escaping (Error?) -> Void) {
83+
// Configure app ID before authenticate
84+
SendBirdCall.configure(appId: credential.appId)
85+
86+
// Authenticate
87+
let authParams = AuthenticateParams(userId: credential.userId, accessToken: credential.accessToken)
88+
SendBirdCall.authenticate(with: authParams) { (user, error) in
89+
guard user != nil else {
90+
// Failed
91+
DispatchQueue.main.async {
92+
completionHandler(error ?? CredentialErrors.unknown)
10793
}
108-
completion()
10994
return
11095
}
111-
112-
completion()
96+
// Succeed
97+
let credential = Credential(accessToken: credential.accessToken)
98+
let credentialManager = CredentialManager.shared
99+
credentialManager.updateCredential(credential)
100+
101+
DispatchQueue.main.async {
102+
completionHandler(nil)
103+
}
113104
}
114105
}
115106
}

0 commit comments

Comments
 (0)