diff --git a/CHANGELOG.md b/CHANGELOG.md index d34c5ea6..4dc0ebee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ * Feat: [Web] Update internal [CallStatus] mapping method. * Fix: [Web] Await Twilio Device `register()` and `unregister()` method calls. * Fix: [Web] Prevent duplicate `TwilioVoiceWeb` instances. +* Feat: [iOS] Add support for call logging via `enableCallLogging(bool)` to record call in recents. No other platform currently supports this, see [NOTES.md](NOTES.md#limitations) for more details. * Feat: update example. * Docs: update CHANGELOG diff --git a/NOTES.md b/NOTES.md index 59965c62..b92b7cf3 100644 --- a/NOTES.md +++ b/NOTES.md @@ -92,6 +92,17 @@ end ## Limitations +### Android + +Android `ConnectionService` provides the fundamentals to managing calls, including but not limited to call logging. Using a Managed `ConnectionService` means that call logging is handled by the system's "Phone App", and so there is not access or control over call logging at this time. + ### macOS -Clearly, macOS isn't uppermost in mind when looking at a mobile first platform like Flutter. There are some functionality limitations for the platform/interop such as [UIImage](https://docs.flutter.dev/ui/assets-and-images#loading-ios-images-in-flutter) support and Twilio Voice library support as a whole. Hopefully we'll be seeing these implemented in future. \ No newline at end of file +Clearly, macOS isn't uppermost in mind when looking at a mobile first platform like Flutter. There are some functionality limitations for the platform/interop such as [UIImage](https://docs.flutter.dev/ui/assets-and-images#loading-ios-images-in-flutter) support and Twilio Voice library support as a whole. Hopefully we'll be seeing these implemented in future. + +With respect to CallKit integration for macOS, there isn't any direct support for CallKit other than via MacCatalyst which at present is somewhat out of scope for the project at this time. + + +### Web + +As Web uses a custom [WebCallkit](https://github.com/cybex-dev/web_callkit) integration, this facilitates basic call management and browser notification integration. Call logging is not supported at this time. \ No newline at end of file diff --git a/ios/Classes/SwiftTwilioVoicePlugin.swift b/ios/Classes/SwiftTwilioVoicePlugin.swift index 9945c35c..b37d8604 100644 --- a/ios/Classes/SwiftTwilioVoicePlugin.swift +++ b/ios/Classes/SwiftTwilioVoicePlugin.swift @@ -10,6 +10,7 @@ public class SwiftTwilioVoicePlugin: NSObject, FlutterPlugin, FlutterStreamHand let callObserver = CXCallObserver() final let defaultCallKitIcon = "callkit_icon" + final let callLoggingEnabledKey = "TV_CALL_LOGGING_ENABLED" var callKitIcon: String? var _result: FlutterResult? @@ -61,6 +62,8 @@ public class SwiftTwilioVoicePlugin: NSObject, FlutterPlugin, FlutterStreamHand configuration.maximumCallGroups = 1 configuration.maximumCallsPerCallGroup = 1 let defaultIcon = UserDefaults.standard.string(forKey: defaultCallKitIcon) ?? defaultCallKitIcon + let callLoggingEnabled = UserDefaults.standard.optionalBool(forKey: callLoggingEnabledKey) ?? true + configuration.includesCallsInRecents = callLoggingEnabled clients = UserDefaults.standard.object(forKey: kClientList) as? [String:String] ?? [:] callKitProvider = CXProvider(configuration: configuration) @@ -356,10 +359,27 @@ public class SwiftTwilioVoicePlugin: NSObject, FlutterPlugin, FlutterStreamHand // update icon & persist result(updateCallKitIcon(icon: newIcon)) return + } else if flutterCall.method == "enableCallLogging" { + let value = arguments["enabled"] as? Bool ?? true + + result(updateEnableCallLogging(value)) + return } result(true) } + /// Set and persist call logging in app preferences + /// - Parameter value: value, true if it should be enabled + func updateEnableCallLogging(_ value: Bool) -> Bool { + // Updating callkit configuration + let configuration = callKitProvider.configuration + configuration.includesCallsInRecents = value + + // Save and persist setting + UserDefaults.standard.set(value, forKey: callLoggingEnabledKey) + return true; + } + /// Updates the CallkitProvider configuration with a new icon, and saves this change to future use. /// - Parameter icon: icon path / name /// - Returns: true if succesful diff --git a/lib/_internal/method_channel/twilio_voice_method_channel.dart b/lib/_internal/method_channel/twilio_voice_method_channel.dart index 37fc981c..cc21dff7 100644 --- a/lib/_internal/method_channel/twilio_voice_method_channel.dart +++ b/lib/_internal/method_channel/twilio_voice_method_channel.dart @@ -442,6 +442,14 @@ class MethodChannelTwilioVoice extends TwilioVoicePlatform { // TODO: implement updateSounds throw UnimplementedError(); } + + @override + Future enableCallLogging({bool enable = true}) { + if (defaultTargetPlatform != TargetPlatform.iOS) { + return Future.value(); + } + return _channel.invokeMethod('enableCallLogging', {"enable": enable}); + } } ActiveCall createCallFromState(String state, {CallDirection? callDirection, bool initiated = false}) { diff --git a/lib/_internal/platform_interface/twilio_voice_platform_interface.dart b/lib/_internal/platform_interface/twilio_voice_platform_interface.dart index 9d3fae28..c21eed4f 100644 --- a/lib/_internal/platform_interface/twilio_voice_platform_interface.dart +++ b/lib/_internal/platform_interface/twilio_voice_platform_interface.dart @@ -197,4 +197,9 @@ abstract class TwilioVoicePlatform extends SharedPlatformInterface { /// Sends call events CallEvent parseCallEvent(String state); + + /// Enable or disable call logging in call manager, or phone app recents. + /// + /// Defaults to true. + Future enableCallLogging({bool enable = true}); }