@cometchat/calls-sdk-react-native 4.0.0-beta1

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.
Files changed (50) hide show
  1. package/README.md +27 -0
  2. package/android/build.gradle +20 -0
  3. package/android/src/main/AndroidManifest.xml +8 -0
  4. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerGeneric.java +213 -0
  5. package/android/src/main/java/com/CometChatCalls/AudioDeviceHandlerLegacy.java +213 -0
  6. package/android/src/main/java/com/CometChatCalls/AudioModeModule.java +456 -0
  7. package/android/src/main/java/com/CometChatCalls/BluetoothHeadsetMonitor.java +174 -0
  8. package/android/src/main/java/com/CometChatCalls/CometChatCallsPackage.java +45 -0
  9. package/cometchat-calls-sdk-react-native.podspec +21 -0
  10. package/dist/CometChatErrorConstants.d.ts +124 -0
  11. package/dist/Constants.d.ts +720 -0
  12. package/dist/Helper copy.d.ts +1 -0
  13. package/dist/Helper.d.ts +7 -0
  14. package/dist/api/APIHandler.d.ts +6 -0
  15. package/dist/api/endpoints.d.ts +6 -0
  16. package/dist/api/helper.d.ts +63 -0
  17. package/dist/api/index.d.ts +2 -0
  18. package/dist/constants/CallConstants.d.ts +136 -0
  19. package/dist/constants/index.d.ts +1 -0
  20. package/dist/defaultCallsettings.d.ts +2 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.js +128 -0
  23. package/dist/models/CallAppSettings.d.ts +42 -0
  24. package/dist/models/CallSettings.d.ts +316 -0
  25. package/dist/models/CometChatCalls.d.ts +89 -0
  26. package/dist/models/CometChatCallsComponent.d.ts +13 -0
  27. package/dist/models/CometChatCallsComponentCore.d.ts +18 -0
  28. package/dist/models/CometChatCallsException.d.ts +7 -0
  29. package/dist/models/CometChatPresenterComponent.d.ts +13 -0
  30. package/dist/models/ErrorModel.d.ts +11 -0
  31. package/dist/models/Listner.d.ts +64 -0
  32. package/dist/models/ListnerHandler.d.ts +10 -0
  33. package/dist/models/MessageComponent.d.ts +7 -0
  34. package/dist/models/PresenterSettings.d.ts +194 -0
  35. package/dist/models/RTCUser.d.ts +18 -0
  36. package/dist/models/index.d.ts +7 -0
  37. package/dist/types/ICallAppSettings.d.ts +6 -0
  38. package/dist/types/ICallSettings.d.ts +60 -0
  39. package/dist/types/RTCUser.d.ts +6 -0
  40. package/dist/types/callEvents.d.ts +53 -0
  41. package/dist/types/common.d.ts +17 -0
  42. package/dist/types/index.d.ts +2 -0
  43. package/ios/AudioMode.h +11 -0
  44. package/ios/AudioMode.m +403 -0
  45. package/ios/JitsiAudioSession+Private.h +25 -0
  46. package/ios/JitsiAudioSession.h +17 -0
  47. package/ios/JitsiAudioSession.m +34 -0
  48. package/ios/LogUtils.h +23 -0
  49. package/ios/react-native-calls2.xcodeproj/project.pbxproj +269 -0
  50. package/package.json +122 -0
@@ -0,0 +1,403 @@
1
+ /*
2
+ * Copyright @ 2017-present 8x8, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import <AVFoundation/AVFoundation.h>
18
+
19
+ #import <React/RCTEventEmitter.h>
20
+ #import <React/RCTLog.h>
21
+ #import <WebRTC/WebRTC.h>
22
+
23
+ #import "JitsiAudioSession+Private.h"
24
+
25
+
26
+ // Audio mode
27
+ typedef enum {
28
+ kAudioModeDefault,
29
+ kAudioModeAudioCall,
30
+ kAudioModeVideoCall
31
+ } JitsiMeetAudioMode;
32
+
33
+ // Events
34
+ static NSString * const kDevicesChanged = @"org.jitsi.meet:features/audio-mode#devices-update";
35
+ static NSString * const kDevicesChangedCustom = @"org.jitsi.meet:features/audio-mode#devices-update-custom";
36
+
37
+ // Device types (must match JS and Java)
38
+ static NSString * const kDeviceTypeBluetooth = @"BLUETOOTH";
39
+ static NSString * const kDeviceTypeCar = @"CAR";
40
+ static NSString * const kDeviceTypeEarpiece = @"EARPIECE";
41
+ static NSString * const kDeviceTypeHeadphones = @"HEADPHONES";
42
+ static NSString * const kDeviceTypeSpeaker = @"SPEAKER";
43
+ static NSString * const kDeviceTypeUnknown = @"UNKNOWN";
44
+
45
+
46
+ @interface AudioMode : RCTEventEmitter<RTCAudioSessionDelegate>
47
+
48
+ @property(nonatomic, strong) dispatch_queue_t workerQueue;
49
+
50
+ @end
51
+
52
+ @implementation AudioMode {
53
+ JitsiMeetAudioMode activeMode;
54
+ RTCAudioSessionConfiguration *defaultConfig;
55
+ RTCAudioSessionConfiguration *audioCallConfig;
56
+ RTCAudioSessionConfiguration *videoCallConfig;
57
+ RTCAudioSessionConfiguration *earpieceConfig;
58
+ BOOL forceSpeaker;
59
+ BOOL forceEarpiece;
60
+ BOOL isSpeakerOn;
61
+ BOOL isEarpieceOn;
62
+ }
63
+
64
+ RCT_EXPORT_MODULE();
65
+
66
+ + (BOOL)requiresMainQueueSetup {
67
+ return NO;
68
+ }
69
+
70
+ - (NSArray<NSString *> *)supportedEvents {
71
+ return @[ kDevicesChanged, kDevicesChangedCustom ];
72
+ }
73
+
74
+ - (NSDictionary *)constantsToExport {
75
+ return @{
76
+ @"DEVICE_CHANGE_EVENT": kDevicesChanged,
77
+ @"DEVICE_CHANGE_EVENT_CUSTOM": kDevicesChangedCustom,
78
+ @"AUDIO_CALL" : [NSNumber numberWithInt: kAudioModeAudioCall],
79
+ @"DEFAULT" : [NSNumber numberWithInt: kAudioModeDefault],
80
+ @"VIDEO_CALL" : [NSNumber numberWithInt: kAudioModeVideoCall]
81
+ };
82
+ };
83
+
84
+ - (instancetype)init {
85
+ self = [super init];
86
+ if (self) {
87
+ dispatch_queue_attr_t attributes =
88
+ dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, -1);
89
+ _workerQueue = dispatch_queue_create("AudioMode.queue", attributes);
90
+
91
+ activeMode = kAudioModeDefault;
92
+
93
+ defaultConfig = [[RTCAudioSessionConfiguration alloc] init];
94
+ defaultConfig.category = AVAudioSessionCategoryAmbient;
95
+ defaultConfig.categoryOptions = 0;
96
+ defaultConfig.mode = AVAudioSessionModeDefault;
97
+
98
+ audioCallConfig = [[RTCAudioSessionConfiguration alloc] init];
99
+ audioCallConfig.category = AVAudioSessionCategoryPlayAndRecord;
100
+ audioCallConfig.categoryOptions = AVAudioSessionCategoryOptionAllowBluetooth | AVAudioSessionCategoryOptionDefaultToSpeaker;
101
+ audioCallConfig.mode = AVAudioSessionModeVoiceChat;
102
+
103
+ videoCallConfig = [[RTCAudioSessionConfiguration alloc] init];
104
+ videoCallConfig.category = AVAudioSessionCategoryPlayAndRecord;
105
+ videoCallConfig.categoryOptions = AVAudioSessionCategoryOptionAllowBluetooth;
106
+ videoCallConfig.mode = AVAudioSessionModeVideoChat;
107
+
108
+ // Manually routing audio to the earpiece doesn't quite work unless one disables BT (weird, I know).
109
+ earpieceConfig = [[RTCAudioSessionConfiguration alloc] init];
110
+ earpieceConfig.category = AVAudioSessionCategoryPlayAndRecord;
111
+ earpieceConfig.categoryOptions = 0;
112
+ earpieceConfig.mode = AVAudioSessionModeVoiceChat;
113
+
114
+ forceSpeaker = NO;
115
+ forceEarpiece = NO;
116
+ isSpeakerOn = NO;
117
+ isEarpieceOn = NO;
118
+
119
+ RTCAudioSession *session = JitsiAudioSession.rtcAudioSession;
120
+ [session addDelegate:self];
121
+ }
122
+
123
+ return self;
124
+ }
125
+
126
+ - (dispatch_queue_t)methodQueue {
127
+ // Use a dedicated queue for audio mode operations.
128
+ return _workerQueue;
129
+ }
130
+
131
+ - (BOOL)setConfigWithoutLock:(RTCAudioSessionConfiguration *)config
132
+ error:(NSError * _Nullable *)outError {
133
+ RTCAudioSession *session = JitsiAudioSession.rtcAudioSession;
134
+
135
+ return [session setConfiguration:config error:outError];
136
+ }
137
+
138
+ - (BOOL)setConfig:(RTCAudioSessionConfiguration *)config
139
+ error:(NSError * _Nullable *)outError {
140
+
141
+ RTCAudioSession *session = JitsiAudioSession.rtcAudioSession;
142
+ [session lockForConfiguration];
143
+ BOOL success = [self setConfigWithoutLock:config error:outError];
144
+ [session unlockForConfiguration];
145
+
146
+ return success;
147
+ }
148
+
149
+ #pragma mark - Exported methods
150
+
151
+ RCT_EXPORT_METHOD(setMode:(int)mode
152
+ resolve:(RCTPromiseResolveBlock)resolve
153
+ reject:(RCTPromiseRejectBlock)reject) {
154
+ RTCAudioSessionConfiguration *config = [self configForMode:mode];
155
+ NSError *error;
156
+
157
+ if (config == nil) {
158
+ reject(@"setMode", @"Invalid mode", nil);
159
+ return;
160
+ }
161
+
162
+ // Reset.
163
+ if (mode == kAudioModeDefault) {
164
+ forceSpeaker = NO;
165
+ forceEarpiece = NO;
166
+ }
167
+
168
+ activeMode = mode;
169
+
170
+ if ([self setConfig:config error:&error]) {
171
+ resolve(nil);
172
+ } else {
173
+ reject(@"setMode", error.localizedDescription, error);
174
+ }
175
+
176
+ [self notifyDevicesChanged];
177
+ }
178
+
179
+ RCT_EXPORT_METHOD(setAudioDevice:(NSString *)device
180
+ resolve:(RCTPromiseResolveBlock)resolve
181
+ reject:(RCTPromiseRejectBlock)reject) {
182
+ NSLog(@"[AudioMode] Selected device: %@", device);
183
+
184
+ RTCAudioSession *session = JitsiAudioSession.rtcAudioSession;
185
+ [session lockForConfiguration];
186
+ BOOL success;
187
+ NSError *error = nil;
188
+
189
+ // Reset these, as we are about to compute them.
190
+ forceSpeaker = NO;
191
+ forceEarpiece = NO;
192
+
193
+ // The speaker is special, so test for it first.
194
+ if ([device isEqualToString:kDeviceTypeSpeaker]) {
195
+ forceSpeaker = YES;
196
+ success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
197
+ } else {
198
+ // Here we use AVAudioSession because RTCAudioSession doesn't expose availableInputs.
199
+ AVAudioSession *_session = [AVAudioSession sharedInstance];
200
+ AVAudioSessionPortDescription *port = nil;
201
+
202
+ // Find the matching input device.
203
+ for (AVAudioSessionPortDescription *portDesc in _session.availableInputs) {
204
+ if ([portDesc.UID isEqualToString:device] || [portDesc.portType isEqualToString:device]) {
205
+ port = portDesc;
206
+ break;
207
+ }
208
+ }
209
+
210
+ if (port != nil) {
211
+ // First remove the override if we are going to select a different device.
212
+ if (isSpeakerOn) {
213
+ [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:nil];
214
+ }
215
+
216
+ // Special case for the earpiece.
217
+ if ([port.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
218
+ forceEarpiece = YES;
219
+ [self setConfigWithoutLock:earpieceConfig error:nil];
220
+ } else if (isEarpieceOn) {
221
+ // Reset the config.
222
+ RTCAudioSessionConfiguration *config = [self configForMode:activeMode];
223
+ [self setConfigWithoutLock:config error:nil];
224
+ }
225
+
226
+ // Select our preferred input.
227
+ success = [session setPreferredInput:port error:&error];
228
+ } else {
229
+ success = NO;
230
+ error = RCTErrorWithMessage(@"Could not find audio device");
231
+ }
232
+ }
233
+
234
+ [session unlockForConfiguration];
235
+
236
+ if (success) {
237
+ [self sendEventWithName:kDevicesChangedCustom body:device];
238
+ resolve(nil);
239
+ } else {
240
+ reject(@"setAudioDevice", error != nil ? error.localizedDescription : @"", error);
241
+ }
242
+ }
243
+
244
+ RCT_EXPORT_METHOD(updateDeviceList) {
245
+ [self notifyDevicesChanged];
246
+ }
247
+
248
+ RCT_EXPORT_METHOD(removeListener) {
249
+ RTCAudioSession *session = [RTCAudioSession sharedInstance];
250
+ [session removeDelegate:self];
251
+ }
252
+ #pragma mark - RTCAudioSessionDelegate
253
+
254
+ - (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
255
+ reason:(AVAudioSessionRouteChangeReason)reason
256
+ previousRoute:(AVAudioSessionRouteDescription *)previousRoute {
257
+ // Update JS about the changes.
258
+ [self notifyDevicesChanged];
259
+
260
+ dispatch_async(_workerQueue, ^{
261
+ switch (reason) {
262
+ case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
263
+ case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
264
+ // If the device list changed, reset our overrides.
265
+ self->forceSpeaker = NO;
266
+ self->forceEarpiece = NO;
267
+ break;
268
+ case AVAudioSessionRouteChangeReasonCategoryChange: {
269
+ // The category has changed. Check if it's the one we want and adjust as
270
+ // needed.
271
+ RTCAudioSessionConfiguration *currentConfig = [self configForMode:self->activeMode];
272
+ if ([session.category isEqualToString:currentConfig.category]) {
273
+ // We are in the desired category, nothing to do here.
274
+ return;
275
+ }
276
+ break;
277
+ }
278
+ default:
279
+ return;
280
+ }
281
+
282
+ // We don't want to touch the category when in default mode.
283
+ // This is to play well with other components which could be integrated
284
+ // into the final application.
285
+ if (self->activeMode != kAudioModeDefault) {
286
+ NSLog(@"[AudioMode] Route changed, reapplying RTCAudioSession config");
287
+ RTCAudioSessionConfiguration *config = [self configForMode:self->activeMode];
288
+ [self setConfig:config error:nil];
289
+ if (self->forceSpeaker && !self->isSpeakerOn) {
290
+ [session lockForConfiguration];
291
+ [session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];
292
+ [session unlockForConfiguration];
293
+ }
294
+ }
295
+ });
296
+ }
297
+
298
+ - (void)audioSession:(RTCAudioSession *)audioSession didSetActive:(BOOL)active {
299
+ NSLog(@"[AudioMode] Audio session didSetActive:%d", active);
300
+ }
301
+
302
+ #pragma mark - Helper methods
303
+
304
+ - (RTCAudioSessionConfiguration *)configForMode:(int) mode {
305
+ if (mode != kAudioModeDefault && forceEarpiece) {
306
+ return earpieceConfig;
307
+ }
308
+
309
+ switch (mode) {
310
+ case kAudioModeAudioCall:
311
+ return audioCallConfig;
312
+ case kAudioModeDefault:
313
+ return defaultConfig;
314
+ case kAudioModeVideoCall:
315
+ return videoCallConfig;
316
+ default:
317
+ return nil;
318
+ }
319
+ }
320
+
321
+ // Here we convert input and output port types into a single type.
322
+ - (NSString *)portTypeToString:(AVAudioSessionPort) portType {
323
+ if ([portType isEqualToString:AVAudioSessionPortHeadphones]
324
+ || [portType isEqualToString:AVAudioSessionPortHeadsetMic]) {
325
+ return kDeviceTypeHeadphones;
326
+ } else if ([portType isEqualToString:AVAudioSessionPortBuiltInMic]
327
+ || [portType isEqualToString:AVAudioSessionPortBuiltInReceiver]) {
328
+ return kDeviceTypeEarpiece;
329
+ } else if ([portType isEqualToString:AVAudioSessionPortBuiltInSpeaker]) {
330
+ return kDeviceTypeSpeaker;
331
+ } else if ([portType isEqualToString:AVAudioSessionPortBluetoothHFP]
332
+ || [portType isEqualToString:AVAudioSessionPortBluetoothLE]
333
+ || [portType isEqualToString:AVAudioSessionPortBluetoothA2DP]) {
334
+ return kDeviceTypeBluetooth;
335
+ } else if ([portType isEqualToString:AVAudioSessionPortCarAudio]) {
336
+ return kDeviceTypeCar;
337
+ } else {
338
+ return kDeviceTypeUnknown;
339
+ }
340
+ }
341
+
342
+ - (void)notifyDevicesChanged {
343
+ NSLog(@"notifyDevicesChanged");
344
+ dispatch_async(_workerQueue, ^{
345
+ NSMutableArray *data = [[NSMutableArray alloc] init];
346
+ // Here we use AVAudioSession because RTCAudioSession doesn't expose availableInputs.
347
+ AVAudioSession *session = [AVAudioSession sharedInstance];
348
+ NSString *currentPort = @"";
349
+ AVAudioSessionRouteDescription *currentRoute = session.currentRoute;
350
+
351
+ // Check what the current device is. Because the speaker is somewhat special, we need to
352
+ // check for it first.
353
+ NSLog(@"notifyDevicesChanged %@", currentRoute);
354
+ if (currentRoute != nil) {
355
+ AVAudioSessionPortDescription *output = currentRoute.outputs.firstObject;
356
+ AVAudioSessionPortDescription *input = currentRoute.inputs.firstObject;
357
+ if (output != nil && [output.portType isEqualToString:AVAudioSessionPortBuiltInSpeaker]) {
358
+ currentPort = kDeviceTypeSpeaker;
359
+ self->isSpeakerOn = YES;
360
+ } else if (input != nil) {
361
+ currentPort = input.UID;
362
+ self->isSpeakerOn = NO;
363
+ self->isEarpieceOn = [input.portType isEqualToString:AVAudioSessionPortBuiltInMic];
364
+ }
365
+ }
366
+
367
+ BOOL headphonesAvailable = NO;
368
+ for (AVAudioSessionPortDescription *portDesc in session.availableInputs) {
369
+ if ([portDesc.portType isEqualToString:AVAudioSessionPortHeadsetMic] || [portDesc.portType isEqualToString:AVAudioSessionPortHeadphones]) {
370
+ headphonesAvailable = YES;
371
+ break;
372
+ }
373
+ }
374
+
375
+ for (AVAudioSessionPortDescription *portDesc in session.availableInputs) {
376
+ // Skip "Phone" if headphones are present.
377
+ if (headphonesAvailable && [portDesc.portType isEqualToString:AVAudioSessionPortBuiltInMic]) {
378
+ continue;
379
+ }
380
+ id deviceData
381
+ = @{
382
+ @"type": [self portTypeToString:portDesc.portType],
383
+ @"name": portDesc.portName,
384
+ @"uid": portDesc.UID,
385
+ @"selected": [NSNumber numberWithBool:[portDesc.UID isEqualToString:currentPort]]
386
+ };
387
+ [data addObject:deviceData];
388
+ }
389
+
390
+ // We need to manually add the speaker because it will never show up in the
391
+ // previous list, as it's not an input.
392
+ [data addObject:
393
+ @{ @"type": kDeviceTypeSpeaker,
394
+ @"name": @"Speaker",
395
+ @"uid": kDeviceTypeSpeaker,
396
+ @"selected": [NSNumber numberWithBool:[kDeviceTypeSpeaker isEqualToString:currentPort]]
397
+ }];
398
+ NSLog(@"notifyDevicesChanged data %@" ,data);
399
+ [self sendEventWithName:kDevicesChanged body:data];
400
+ });
401
+ }
402
+
403
+ @end
@@ -0,0 +1,25 @@
1
+
2
+ /*
3
+ * Copyright @ 2017-present 8x8, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #import "JitsiAudioSession.h"
19
+ #import <WebRTC/WebRTC.h>
20
+
21
+ @interface JitsiAudioSession (Private)
22
+
23
+ + (RTCAudioSession *)rtcAudioSession;
24
+
25
+ @end
@@ -0,0 +1,17 @@
1
+ //
2
+ // JitsiAudioSession.h
3
+ // CometChatProCalls
4
+ //
5
+ // Created by CometChat on 27/05/22.
6
+ // Copyright © 2022 Jitsi. All rights reserved.
7
+ //
8
+
9
+ #import <Foundation/Foundation.h>
10
+
11
+ NS_ASSUME_NONNULL_BEGIN
12
+
13
+ @interface JitsiAudioSession : NSObject
14
+
15
+ @end
16
+
17
+ NS_ASSUME_NONNULL_END
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Copyright @ 2017-present 8x8, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #import "JitsiAudioSession.h"
18
+ #import "JitsiAudioSession+Private.h"
19
+
20
+ @implementation JitsiAudioSession
21
+
22
+ + (RTCAudioSession *)rtcAudioSession {
23
+ return [RTCAudioSession sharedInstance];
24
+ }
25
+
26
+ + (void)activateWithAudioSession:(AVAudioSession *)session {
27
+ [self.rtcAudioSession audioSessionDidActivate:session];
28
+ }
29
+
30
+ + (void)deactivateWithAudioSession:(AVAudioSession *)session {
31
+ [self.rtcAudioSession audioSessionDidDeactivate:session];
32
+ }
33
+
34
+ @end
package/ios/LogUtils.h ADDED
@@ -0,0 +1,23 @@
1
+ /*
2
+ * Copyright @ 2019-present 8x8, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #ifndef JM_LOG_UTILS_H
18
+ #define JM_LOG_UTILS_H
19
+
20
+ #import <CocoaLumberjack/CocoaLumberjack.h>
21
+ static const DDLogLevel ddLogLevel = DDLogLevelVerbose;
22
+
23
+ #endif