@kaleyra/video-react-native-module 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -2
- package/android/src/main/assets/kaleyra_video_wrapper_info.txt +1 -1
- package/ios/PluginInfo/_KaleyraVideoHybridVersionInfo.swift +1 -1
- package/native-bridge/android/build.gradle +1 -1
- package/native-bridge/android/src/main/java/com/kaleyra/video_hybrid_native_bridge/notifications/KaleyraVideoNotificationReceiver.kt +20 -23
- package/native-bridge/android/src/main/java/com/kaleyra/video_hybrid_native_bridge/notifications/KaleyraVideoNotificationService.kt +5 -5
- package/native-bridge/iOS/KaleyraVideoHybridNativeBridge.xcodeproj/project.pbxproj +12 -4
- package/native-bridge/iOS/Podfile +1 -1
- package/native-bridge/iOS/Podfile.lock +6 -6
- package/native-bridge/iOS/Source/Concurrency/Atomic.swift +116 -0
- package/native-bridge/iOS/Source/Concurrency/{Lock.swift → Locking.swift} +4 -4
- package/native-bridge/iOS/Source/NativeHybridBridge/VideoHybridNativeBridge.swift +0 -2
- package/native-bridge/iOS/Source/User Details/Cache/UsersDetailsCache.swift +1 -1
- package/native-bridge/iOS/Source/User Details/Formatter/FormatterProxy.swift +3 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -105,18 +105,43 @@ Example:
|
|
|
105
105
|
kaleyraVideo.events.onCallModuleStatusChanged = (status: String) => {};
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
##
|
|
108
|
+
## iOS - VoIP Notifications
|
|
109
109
|
|
|
110
|
+
### Setup required for VoIP notifications
|
|
111
|
+
|
|
112
|
+
If you desire to use VoIP notifications on iOS platform as first thing you should configure kaleyraVideo passing a config object as follow:
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
var kaleyraVideo = KaleyraVideo.configure({
|
|
116
|
+
[...]
|
|
117
|
+
iosConfig: {
|
|
118
|
+
voipHandlingStrategy: VoipHandlingStrategy.AUTOMATIC,
|
|
119
|
+
[...]
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
The iOS project requires a little setup for use VoIP notifications. [Here][iOSProjectSetup] you can find a description of how the project should be configured.
|
|
125
|
+
|
|
126
|
+
### Listening for VoIP push token
|
|
110
127
|
In order to get your device push token, you must listen for the **KaleyraVideo.events.iOSVoipPushTokenUpdated** event registering a callback as follows:
|
|
111
128
|
|
|
112
129
|
```javascript
|
|
130
|
+
// The token is received in this listener only after calling kaleyraVideo.connect(_)
|
|
113
131
|
kaleyraVideo.events.oniOSVoipPushTokenUpdated = (token: string) => {
|
|
114
132
|
// register the VoIP push token on your server
|
|
115
133
|
});
|
|
116
134
|
```
|
|
117
|
-
|
|
135
|
+
**Warning:** Make sure this listener is attached before calling kaleyraVideo.connect(_), otherwise the event reporting the device token could be missed.
|
|
136
|
+
|
|
137
|
+
The token provided in the callback is the **string** representation of your device token.
|
|
118
138
|
Here's an example of a device token: **dec105f879924349fd2fa9aa8bb8b70431d5f41d57bfa8e31a5d80a629774fd9**
|
|
119
139
|
|
|
140
|
+
### VoIP notification payload
|
|
141
|
+
|
|
142
|
+
[Here][iOSVoIPPayload] you can find an example of how your VoIP notifications payload should be structured.
|
|
143
|
+
|
|
144
|
+
|
|
120
145
|
## Module connect
|
|
121
146
|
|
|
122
147
|
To connect the plugin to the Kaleyra Video system you will need to provide a Session object.
|
|
@@ -288,5 +313,7 @@ The API documentation is available on the github pages link:
|
|
|
288
313
|
[LinkNpm]: https://www.npmjs.com/package/@kaleyra/video-react-native-module
|
|
289
314
|
[BroadcastAchor]: #ios-broadcast-screen-sharing
|
|
290
315
|
[BroadcastSceenSharing]: https://github.com/Bandyer/Bandyer-iOS-SDK/wiki/Screen-sharing#broadcast-screen-sharing
|
|
316
|
+
[iOSProjectSetup]: https://github.com/Bandyer/Bandyer-iOS-SDK/wiki/VOIP-notifications#project-setup
|
|
317
|
+
[iOSVoIPPayload]: https://github.com/Bandyer/Bandyer-iOS-SDK/wiki/VOIP-notifications#notification-payload-key-path
|
|
291
318
|
[EventsDoc]: https://kaleyravideo.github.io/VideoReactNativeModule/interfaces/src_events_Events.Events.html
|
|
292
319
|
[TSDoc]: https://kaleyravideo.github.io/VideoReactNativeModule/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
React/1.0.
|
|
1
|
+
React/1.0.1
|
|
@@ -57,7 +57,7 @@ android {
|
|
|
57
57
|
dependencies {
|
|
58
58
|
implementation 'com.google.code.gson:gson:2.9.1'
|
|
59
59
|
implementation "com.kaleyra:collaboration-suite-utils:3.0.3"
|
|
60
|
-
implementation "com.bandyer:bandyer-android-sdk:3.6.
|
|
60
|
+
implementation "com.bandyer:bandyer-android-sdk:3.6.2"
|
|
61
61
|
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
|
|
62
62
|
compileOnly "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.1"
|
|
63
63
|
implementation "androidx.room:room-runtime:2.4.2"
|
|
@@ -11,9 +11,6 @@ import android.content.Intent
|
|
|
11
11
|
import android.content.pm.PackageManager
|
|
12
12
|
import android.os.Bundle
|
|
13
13
|
import android.util.Log
|
|
14
|
-
//import com.bandyer.flutter_plugin.exceptions.PluginNotificationKeyNotFound
|
|
15
|
-
//import com.bandyer.flutter_plugin.exceptions.NotificationPayloadDataPathNotDefined
|
|
16
|
-
//import com.bandyer.flutter_plugin.extensions.asJSONObject
|
|
17
14
|
import org.json.JSONObject
|
|
18
15
|
|
|
19
16
|
/**
|
|
@@ -36,20 +33,20 @@ class KaleyraVideoNotificationReceiver : BroadcastReceiver() {
|
|
|
36
33
|
return
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
// check if a
|
|
40
|
-
val serviceIntent = Intent().setAction("com.
|
|
36
|
+
// check if a kaleyra video notification service was defined in the manifest
|
|
37
|
+
val serviceIntent = Intent().setAction("com.kaleyra.VideoNotificationEvent").setPackage(context.packageName)
|
|
41
38
|
val resolveInfo = context.packageManager.queryIntentServices(serviceIntent, PackageManager.GET_RESOLVED_FILTER)
|
|
42
39
|
if (resolveInfo.size < 1) return
|
|
43
40
|
|
|
44
|
-
val
|
|
41
|
+
val kaleyraVideoPayloadPath: String
|
|
45
42
|
try {
|
|
46
|
-
|
|
43
|
+
kaleyraVideoPayloadPath = resolveInfo[0].filter.getDataPath(0).path
|
|
47
44
|
} catch (e: Throwable) {
|
|
48
|
-
throw Throwable("You have not defined data path in your intent-filter!!
|
|
45
|
+
throw Throwable("You have not defined data path in your intent-filter!! Kaleyra video requires it to know where to find the payload!")
|
|
49
46
|
}
|
|
50
47
|
|
|
51
|
-
val payload =
|
|
52
|
-
// if
|
|
48
|
+
val payload = getNotificationPayload(intent, kaleyraVideoPayloadPath)
|
|
49
|
+
// if kaleyra video can handle payload proceed
|
|
53
50
|
if (payload == null) {
|
|
54
51
|
resultCode = Activity.RESULT_OK
|
|
55
52
|
return
|
|
@@ -66,32 +63,32 @@ class KaleyraVideoNotificationReceiver : BroadcastReceiver() {
|
|
|
66
63
|
resultCode = Activity.RESULT_OK
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
private fun
|
|
66
|
+
private fun getNotificationPayload(intent: Intent, notificationPayloadPath: String): String? {
|
|
70
67
|
try {
|
|
71
|
-
val keyPath =
|
|
68
|
+
val keyPath = notificationPayloadPath.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
72
69
|
val payload = intent.extras!!.asJSONObject()
|
|
73
|
-
if (!payload.toString().
|
|
70
|
+
if (!payload.toString().isKaleyraNotification()) return null
|
|
74
71
|
if (!payload.has(keyPath[0]))
|
|
75
72
|
throw PluginNotificationKeyNotFound("\nRequired jsonObject:" + keyPath[0] + " is not contained in " + payload.keys().asString())
|
|
76
|
-
var
|
|
73
|
+
var kaleyraPayloadData = payload.getString(keyPath[0])
|
|
77
74
|
for (i in 1 until keyPath.size) {
|
|
78
|
-
val data = JSONObject(
|
|
75
|
+
val data = JSONObject(kaleyraPayloadData)
|
|
79
76
|
if (!data.has(keyPath[i]))
|
|
80
77
|
throw PluginNotificationKeyNotFound("\nRequired jsonObject:" + keyPath[i] + " is not contained in " + payload.keys().asString())
|
|
81
|
-
|
|
78
|
+
kaleyraPayloadData = JSONObject(kaleyraPayloadData).getString(keyPath[i])
|
|
82
79
|
}
|
|
83
|
-
return
|
|
80
|
+
return kaleyraPayloadData
|
|
84
81
|
} catch (e: Throwable) {
|
|
85
82
|
if (e is PluginNotificationKeyNotFound) {
|
|
86
83
|
Log.w(
|
|
87
|
-
"
|
|
88
|
-
"\nThis notification will not be handled by
|
|
89
|
-
"\
|
|
84
|
+
"KaleyraNotReceiver", "Failed to handle notification!!!" + e.message +
|
|
85
|
+
"\nThis notification will not be handled by Kaleyra!" +
|
|
86
|
+
"\nKaleyra payload not found in the following path: " + notificationPayloadPath
|
|
90
87
|
)
|
|
91
88
|
} else
|
|
92
89
|
Log.w(
|
|
93
|
-
"
|
|
94
|
-
"\nThis notification will not be handled by
|
|
90
|
+
"KaleyraNotReceiver", "Failed to handle notification!!!" +
|
|
91
|
+
"\nThis notification will not be handled by Kaleyra!" +
|
|
95
92
|
e.localizedMessage!!
|
|
96
93
|
)
|
|
97
94
|
}
|
|
@@ -109,7 +106,7 @@ class KaleyraVideoNotificationReceiver : BroadcastReceiver() {
|
|
|
109
106
|
return value.toString()
|
|
110
107
|
}
|
|
111
108
|
|
|
112
|
-
private fun String.
|
|
109
|
+
private fun String.isKaleyraNotification(): Boolean = contains("on_call_incoming") || contains("on_message_sent");
|
|
113
110
|
|
|
114
111
|
private fun isGcmMessage(intent: Intent): Boolean {
|
|
115
112
|
if (GCM_RECEIVE_ACTION == intent.action) {
|
|
@@ -42,13 +42,13 @@ class KaleyraVideoNotificationService : JobIntentService() {
|
|
|
42
42
|
val extras = intent.extras ?: return
|
|
43
43
|
val payload = extras.getString("payload") ?: return
|
|
44
44
|
try {
|
|
45
|
-
val
|
|
46
|
-
val
|
|
45
|
+
val webHookPayload = JSONObject(payload).get("payload").toString()
|
|
46
|
+
val userToken = JSONObject(payload).getString("user_token")
|
|
47
47
|
|
|
48
48
|
val scope = CoroutineScope(Executors.newSingleThreadExecutor().asCoroutineDispatcher())
|
|
49
49
|
val plugin = VideoSDKHybridBridge(
|
|
50
50
|
contextContainer = ServiceContextContainer(),
|
|
51
|
-
tokenProvider = SingleTokenProvider(
|
|
51
|
+
tokenProvider = SingleTokenProvider(userToken),
|
|
52
52
|
backgroundScope = scope,
|
|
53
53
|
eventsReporter = NoOpEventsReporter(),
|
|
54
54
|
eventsEmitter = NoOpEventsEmitter(),
|
|
@@ -59,10 +59,10 @@ class KaleyraVideoNotificationService : JobIntentService() {
|
|
|
59
59
|
plugin.addUsersDetails(plugin.cachedUserDetails.toTypedArray())
|
|
60
60
|
plugin.configureBridge(savedConfiguration)
|
|
61
61
|
plugin.connect(savedUsed)
|
|
62
|
-
plugin.handlePushNotificationPayload(
|
|
62
|
+
plugin.handlePushNotificationPayload(webHookPayload)
|
|
63
63
|
}
|
|
64
64
|
} catch (exception: Throwable) {
|
|
65
|
-
Log.e("
|
|
65
|
+
Log.e("KaleyraNotService", "" + exception.message)
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
F9875C7529A661FC00A91C93 /* KaleyraVideoHybridNativeBridge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9875C6C29A661FC00A91C93 /* KaleyraVideoHybridNativeBridge.framework */; };
|
|
28
28
|
F9875C7B29A661FC00A91C93 /* KaleyraVideoHybridNativeBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = F9875C6F29A661FC00A91C93 /* KaleyraVideoHybridNativeBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
|
29
29
|
F9875CC129A663B300A91C93 /* MainQueueDispatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9875C8529A663B200A91C93 /* MainQueueDispatcher.swift */; };
|
|
30
|
-
F9875CC229A663B300A91C93 /*
|
|
30
|
+
F9875CC229A663B300A91C93 /* Locking.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9875C8629A663B200A91C93 /* Locking.swift */; };
|
|
31
31
|
F9875CC329A663B300A91C93 /* DispatchQueue+isMain.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9875C8729A663B200A91C93 /* DispatchQueue+isMain.swift */; };
|
|
32
32
|
F9875CC429A663B300A91C93 /* DTOs.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9875C8929A663B200A91C93 /* DTOs.swift */; };
|
|
33
33
|
F9875CC529A663B300A91C93 /* CallType+Bandyer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9875C8A29A663B200A91C93 /* CallType+Bandyer.swift */; };
|
|
@@ -133,6 +133,8 @@
|
|
|
133
133
|
F9B7E5A929E5912700AB9208 /* CreateCallOptions+Equatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9B7E5A829E5912700AB9208 /* CreateCallOptions+Equatable.swift */; };
|
|
134
134
|
F9B7E5AB29E5913E00AB9208 /* CreateCallOptions+EquatableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9B7E5AA29E5913E00AB9208 /* CreateCallOptions+EquatableTests.swift */; };
|
|
135
135
|
F9B7E5AE29E5A4BA00AB9208 /* CallWindowProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9B7E5AD29E5A4BA00AB9208 /* CallWindowProtocol.swift */; };
|
|
136
|
+
F9BEA4C02A7A9F940066988B /* AtomicTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9BEA4BF2A7A9F940066988B /* AtomicTests.swift */; };
|
|
137
|
+
F9BEA4C22A7A9FA60066988B /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9BEA4C12A7A9FA60066988B /* Atomic.swift */; };
|
|
136
138
|
F9C6F96629DDBB610094DB30 /* CallDoubles.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C6F96529DDBB610094DB30 /* CallDoubles.swift */; };
|
|
137
139
|
F9C6F96829DDBD980094DB30 /* CallRegistryDoubles.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9C6F96729DDBD980094DB30 /* CallRegistryDoubles.swift */; };
|
|
138
140
|
F9DEA4DA29E83C840011D222 /* MainQueueRelay.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9DEA4D929E83C840011D222 /* MainQueueRelay.swift */; };
|
|
@@ -188,7 +190,7 @@
|
|
|
188
190
|
F9875C6F29A661FC00A91C93 /* KaleyraVideoHybridNativeBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KaleyraVideoHybridNativeBridge.h; sourceTree = "<group>"; };
|
|
189
191
|
F9875C7429A661FC00A91C93 /* KaleyraVideoHybridNativeBridgeTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KaleyraVideoHybridNativeBridgeTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
|
190
192
|
F9875C8529A663B200A91C93 /* MainQueueDispatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainQueueDispatcher.swift; sourceTree = "<group>"; };
|
|
191
|
-
F9875C8629A663B200A91C93 /*
|
|
193
|
+
F9875C8629A663B200A91C93 /* Locking.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Locking.swift; sourceTree = "<group>"; };
|
|
192
194
|
F9875C8729A663B200A91C93 /* DispatchQueue+isMain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+isMain.swift"; sourceTree = "<group>"; };
|
|
193
195
|
F9875C8929A663B200A91C93 /* DTOs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DTOs.swift; sourceTree = "<group>"; };
|
|
194
196
|
F9875C8A29A663B200A91C93 /* CallType+Bandyer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CallType+Bandyer.swift"; sourceTree = "<group>"; };
|
|
@@ -294,6 +296,8 @@
|
|
|
294
296
|
F9B7E5A829E5912700AB9208 /* CreateCallOptions+Equatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CreateCallOptions+Equatable.swift"; sourceTree = "<group>"; };
|
|
295
297
|
F9B7E5AA29E5913E00AB9208 /* CreateCallOptions+EquatableTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CreateCallOptions+EquatableTests.swift"; sourceTree = "<group>"; };
|
|
296
298
|
F9B7E5AD29E5A4BA00AB9208 /* CallWindowProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallWindowProtocol.swift; sourceTree = "<group>"; };
|
|
299
|
+
F9BEA4BF2A7A9F940066988B /* AtomicTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AtomicTests.swift; sourceTree = "<group>"; };
|
|
300
|
+
F9BEA4C12A7A9FA60066988B /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
|
|
297
301
|
F9C6F96529DDBB610094DB30 /* CallDoubles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallDoubles.swift; sourceTree = "<group>"; };
|
|
298
302
|
F9C6F96729DDBD980094DB30 /* CallRegistryDoubles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CallRegistryDoubles.swift; sourceTree = "<group>"; };
|
|
299
303
|
F9DEA4D929E83C840011D222 /* MainQueueRelay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainQueueRelay.swift; sourceTree = "<group>"; };
|
|
@@ -440,8 +444,9 @@
|
|
|
440
444
|
F9875C8429A663B200A91C93 /* Concurrency */ = {
|
|
441
445
|
isa = PBXGroup;
|
|
442
446
|
children = (
|
|
447
|
+
F9BEA4C12A7A9FA60066988B /* Atomic.swift */,
|
|
443
448
|
F9875C8729A663B200A91C93 /* DispatchQueue+isMain.swift */,
|
|
444
|
-
F9875C8629A663B200A91C93 /*
|
|
449
|
+
F9875C8629A663B200A91C93 /* Locking.swift */,
|
|
445
450
|
F9875C8529A663B200A91C93 /* MainQueueDispatcher.swift */,
|
|
446
451
|
F9DEA4D929E83C840011D222 /* MainQueueRelay.swift */,
|
|
447
452
|
);
|
|
@@ -623,6 +628,7 @@
|
|
|
623
628
|
F9875D0229A6650A00A91C93 /* Concurrency */ = {
|
|
624
629
|
isa = PBXGroup;
|
|
625
630
|
children = (
|
|
631
|
+
F9BEA4BF2A7A9F940066988B /* AtomicTests.swift */,
|
|
626
632
|
F9875D0329A6650A00A91C93 /* DispatchQueue+isMainTests.swift */,
|
|
627
633
|
F9875D0429A6650A00A91C93 /* MainQueueDispatcherTests.swift */,
|
|
628
634
|
F9DEA4DB29E83F400011D222 /* MainQueueRelayTests.swift */,
|
|
@@ -1000,6 +1006,7 @@
|
|
|
1000
1006
|
F931C8B429DEF24600194E1D /* KaleyraVideoSDKUserInterfacePresenter.swift in Sources */,
|
|
1001
1007
|
F9875CC329A663B300A91C93 /* DispatchQueue+isMain.swift in Sources */,
|
|
1002
1008
|
F9875CE729A663B300A91C93 /* ChatClientEventsReporter.swift in Sources */,
|
|
1009
|
+
F9BEA4C22A7A9FA60066988B /* Atomic.swift in Sources */,
|
|
1003
1010
|
F9B7E59929E5602800AB9208 /* CallOptions+Bandyer.swift in Sources */,
|
|
1004
1011
|
F967342529D2EFE500F9B914 /* TokenProvider.swift in Sources */,
|
|
1005
1012
|
F9875CDE29A663B300A91C93 /* Array+JSON.swift in Sources */,
|
|
@@ -1018,7 +1025,7 @@
|
|
|
1018
1025
|
F96C93F729E8442F004FA995 /* UserInterfacePresenter+MainQueueRelay.swift in Sources */,
|
|
1019
1026
|
F9875CD829A663B300A91C93 /* AccessTokenRequest+Encodable.swift in Sources */,
|
|
1020
1027
|
F9875CE229A663B300A91C93 /* RecordingType+Decodable.swift in Sources */,
|
|
1021
|
-
F9875CC229A663B300A91C93 /*
|
|
1028
|
+
F9875CC229A663B300A91C93 /* Locking.swift in Sources */,
|
|
1022
1029
|
F9875CC929A663B300A91C93 /* CallType+Decodable.swift in Sources */,
|
|
1023
1030
|
F9875CD729A663B300A91C93 /* AccessTokenResponse+Decodable.swift in Sources */,
|
|
1024
1031
|
F9DEA4DA29E83C840011D222 /* MainQueueRelay.swift in Sources */,
|
|
@@ -1100,6 +1107,7 @@
|
|
|
1100
1107
|
F9875D3429A6650A00A91C93 /* CreateCallOptions+IntentTests.swift in Sources */,
|
|
1101
1108
|
F9B7E5A129E5663900AB9208 /* AudioCallOptions+EquatableTests.swift in Sources */,
|
|
1102
1109
|
F9875D5329A6650A00A91C93 /* TestHelpers.swift in Sources */,
|
|
1110
|
+
F9BEA4C02A7A9F940066988B /* AtomicTests.swift in Sources */,
|
|
1103
1111
|
F9875D5729A6650A00A91C93 /* UnitTestCase.swift in Sources */,
|
|
1104
1112
|
F9B7E5A729E5888E00AB9208 /* KaleyraVideoConfiguration+UserInterfacePresenterConfigurationTests.swift in Sources */,
|
|
1105
1113
|
F9875D3E29A6650A00A91C93 /* RegionTests.swift in Sources */,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
PODS:
|
|
2
|
-
- Bandyer (3.
|
|
3
|
-
- SwiftHamcrest (2.2.
|
|
2
|
+
- Bandyer (3.7.1)
|
|
3
|
+
- SwiftHamcrest (2.2.2)
|
|
4
4
|
|
|
5
5
|
DEPENDENCIES:
|
|
6
|
-
- Bandyer
|
|
6
|
+
- Bandyer
|
|
7
7
|
- SwiftHamcrest (~> 2.2)
|
|
8
8
|
|
|
9
9
|
SPEC REPOS:
|
|
@@ -12,9 +12,9 @@ SPEC REPOS:
|
|
|
12
12
|
- SwiftHamcrest
|
|
13
13
|
|
|
14
14
|
SPEC CHECKSUMS:
|
|
15
|
-
Bandyer:
|
|
16
|
-
SwiftHamcrest:
|
|
15
|
+
Bandyer: 6e08c8a3998b67dda18dd3646833b250138b6a5f
|
|
16
|
+
SwiftHamcrest: 940c3dae2a31f92da433f5a0b13d42103247051b
|
|
17
17
|
|
|
18
|
-
PODFILE CHECKSUM:
|
|
18
|
+
PODFILE CHECKSUM: 4dcc6d8e15f107f998b14af91b4d8f58cea31d08
|
|
19
19
|
|
|
20
20
|
COCOAPODS: 1.12.1
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// Copyright © 2018-2023 Kaleyra S.p.a. All Rights Reserved.
|
|
2
|
+
// See LICENSE for licensing information
|
|
3
|
+
|
|
4
|
+
import Foundation
|
|
5
|
+
|
|
6
|
+
@propertyWrapper
|
|
7
|
+
class Atomic<Value> {
|
|
8
|
+
|
|
9
|
+
private var value: Value
|
|
10
|
+
private let lock: Locking
|
|
11
|
+
|
|
12
|
+
init(wrappedValue: Value, lock: Locking = NSLock()) {
|
|
13
|
+
self.value = wrappedValue
|
|
14
|
+
self.lock = lock
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
init(_ value: Value, lock: Locking = NSLock()) {
|
|
18
|
+
self.value = value
|
|
19
|
+
self.lock = lock
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var wrappedValue: Value {
|
|
23
|
+
get {
|
|
24
|
+
lock.sync {
|
|
25
|
+
value
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
set {
|
|
30
|
+
lock.sync {
|
|
31
|
+
value = newValue
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
var projectedValue: Atomic<Value> { self }
|
|
37
|
+
|
|
38
|
+
func `do`(_ body: (inout Value) throws -> Void) rethrows {
|
|
39
|
+
try lock.sync { try body(&value) }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func `do`<T>(_ body: (inout Value) throws -> T) rethrows -> T {
|
|
43
|
+
try lock.sync { try body(&value) }
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func swap(_ newValue: Value) -> Value {
|
|
47
|
+
lock.sync {
|
|
48
|
+
let oldValue = value
|
|
49
|
+
value = newValue
|
|
50
|
+
return oldValue
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
extension Atomic: Equatable where Value: Equatable {
|
|
56
|
+
|
|
57
|
+
static func == (lhs: Atomic<Value>, rhs: Atomic<Value>) -> Bool {
|
|
58
|
+
lhs.wrappedValue == rhs.wrappedValue
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
extension Atomic where Value: Equatable {
|
|
63
|
+
|
|
64
|
+
static func == (lhs: Atomic<Value>, rhs: Value) -> Bool {
|
|
65
|
+
lhs.wrappedValue == rhs
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
static func == (lhs: Value, rhs: Atomic<Value>) -> Bool {
|
|
69
|
+
lhs == rhs.wrappedValue
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
extension Atomic where Value: AdditiveArithmetic {
|
|
74
|
+
|
|
75
|
+
static func += (lhs: Atomic<Value>, rhs: Value) {
|
|
76
|
+
lhs.do { $0 += rhs }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static func += (lhs: inout Value, rhs: Atomic<Value>) {
|
|
80
|
+
lhs += rhs.wrappedValue
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static func -= (lhs: Atomic<Value>, rhs: Value) {
|
|
84
|
+
lhs.do { $0 -= rhs }
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static func -= (lhs: inout Value, rhs: Atomic<Value>) {
|
|
88
|
+
lhs -= rhs.wrappedValue
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
extension Atomic where Value: Collection {
|
|
93
|
+
|
|
94
|
+
var count: Int { wrappedValue.count }
|
|
95
|
+
|
|
96
|
+
var isEmpty: Bool { wrappedValue.isEmpty }
|
|
97
|
+
|
|
98
|
+
subscript(index: Value.Index) -> Value.Element {
|
|
99
|
+
wrappedValue[index]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
func dropFirst(_ k: Int = 1) -> Value.SubSequence {
|
|
103
|
+
wrappedValue.dropFirst(k)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
func dropLast(_ k: Int = 1) -> Value.SubSequence {
|
|
107
|
+
wrappedValue.dropLast(k)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
extension Atomic where Value: RangeReplaceableCollection {
|
|
112
|
+
|
|
113
|
+
func append(_ newElement: Value.Element) {
|
|
114
|
+
self.do { $0.append(newElement) }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
|
|
4
4
|
import Foundation
|
|
5
5
|
|
|
6
|
-
protocol
|
|
6
|
+
protocol Locking {
|
|
7
7
|
|
|
8
8
|
func sync<T>(_ work: () throws -> T) rethrows -> T
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
extension
|
|
11
|
+
extension Locking where Self: NSLocking {
|
|
12
12
|
|
|
13
13
|
func sync<T>(_ work: () throws -> T) rethrows -> T {
|
|
14
14
|
lock()
|
|
@@ -17,5 +17,5 @@ extension Lock where Self: NSLocking {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
extension NSLock:
|
|
21
|
-
extension NSRecursiveLock:
|
|
20
|
+
extension NSLock: Locking {}
|
|
21
|
+
extension NSRecursiveLock: Locking {}
|
|
@@ -83,7 +83,6 @@ class VideoHybridNativeBridge {
|
|
|
83
83
|
|
|
84
84
|
func connect(userID: String) throws {
|
|
85
85
|
try checkIsConfigured()
|
|
86
|
-
|
|
87
86
|
let provider = accessTokenProviderFactory()
|
|
88
87
|
sdk.connect(Bandyer.Session(userId: userID, tokenProvider: provider))
|
|
89
88
|
}
|
|
@@ -120,7 +119,6 @@ class VideoHybridNativeBridge {
|
|
|
120
119
|
try checkIsConfigured()
|
|
121
120
|
|
|
122
121
|
sdk.disconnect()
|
|
123
|
-
reporter.stop()
|
|
124
122
|
}
|
|
125
123
|
|
|
126
124
|
func addUsersDetails(_ details: [UserDetails]) {
|
|
@@ -8,7 +8,7 @@ import Bandyer
|
|
|
8
8
|
class UsersDetailsCache {
|
|
9
9
|
|
|
10
10
|
private lazy var items = [String : Bandyer.UserDetails]()
|
|
11
|
-
private let lock:
|
|
11
|
+
private let lock: Locking = NSRecursiveLock()
|
|
12
12
|
|
|
13
13
|
func setItem(_ item: Bandyer.UserDetails, forKey key: String) {
|
|
14
14
|
lock.sync {
|
|
@@ -6,42 +6,11 @@ import Foundation
|
|
|
6
6
|
@available(iOS 12.0, *)
|
|
7
7
|
class FormatterProxy: Formatter {
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
private let lock: Lock = NSRecursiveLock()
|
|
12
|
-
private var _formatter: Formatter
|
|
13
|
-
|
|
14
|
-
var formatter: Formatter! {
|
|
15
|
-
get {
|
|
16
|
-
lock.sync {
|
|
17
|
-
_formatter
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
set {
|
|
22
|
-
lock.sync {
|
|
23
|
-
guard newValue != nil else {
|
|
24
|
-
_formatter = Self.defaultFormatter
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
_formatter = newValue
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
override init() {
|
|
34
|
-
_formatter = Self.defaultFormatter
|
|
35
|
-
super.init()
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
required init?(coder: NSCoder) {
|
|
39
|
-
_formatter = Self.defaultFormatter
|
|
40
|
-
super.init(coder: coder)
|
|
41
|
-
}
|
|
9
|
+
@Atomic
|
|
10
|
+
var formatter: Formatter?
|
|
42
11
|
|
|
43
12
|
override func string(for obj: Any?) -> String? {
|
|
44
|
-
formatter
|
|
13
|
+
formatter?.string(for: obj)
|
|
45
14
|
}
|
|
46
15
|
|
|
47
16
|
}
|