diff --git a/ios/Classes/Constants.swift b/ios/Classes/Constants.swift index 79753fb..37cab1d 100644 --- a/ios/Classes/Constants.swift +++ b/ios/Classes/Constants.swift @@ -23,4 +23,23 @@ struct Constants { struct Error { static let methodNotImplemented = "Method not implemented" } + + struct Arguments { + static let firstName = "fname" + static let lastName = "lname" + static let otp = "otp" + static let phone = "ph" + static let countryCode = "ci" + } + + struct CountryCode { + static let india = "IN" + } + + struct ErrorDescription { + static let unableToParseArguments = "Unable to parse arguments" + static let phoneNumberEmpty = "Phone number cannot be empty" + static let firstNameEmpty = "Firstname should not be empty" + static let otpEmpty = "OTP should not be empty" + } } diff --git a/ios/Classes/Extensions.swift b/ios/Classes/Extensions.swift index 7f71cfe..cf00bff 100644 --- a/ios/Classes/Extensions.swift +++ b/ios/Classes/Extensions.swift @@ -46,7 +46,7 @@ extension TCTrueProfile { extension TCError { var toDict: [String: AnyHashable] { var dict = [String: AnyHashable]() - dict["code"] = getCode() + dict["code"] = getCode().rawValue dict["message"] = description return dict } diff --git a/ios/Classes/SwiftTruecallerSdkPlugin.swift b/ios/Classes/SwiftTruecallerSdkPlugin.swift index 9879a01..2cc845e 100644 --- a/ios/Classes/SwiftTruecallerSdkPlugin.swift +++ b/ios/Classes/SwiftTruecallerSdkPlugin.swift @@ -13,12 +13,17 @@ private enum MethodCalls: String { case verifyMissedCall } +//Disclaimer should be manually shown while using iOS flutter SDK. +public class Controller: UIViewController, TCTrueSDKViewDelegate { } + public class SwiftTruecallerSdkPlugin: NSObject, FlutterPlugin { private var mainChannel: FlutterMethodChannel? private var eventChannel: FlutterEventChannel? private var eventSink: FlutterEventSink? + private var controller = Controller() + private var trueSdk = TCTrueSDK.sharedManager() public static func register(with registrar: FlutterPluginRegistrar) { @@ -59,21 +64,90 @@ public class SwiftTruecallerSdkPlugin: NSObject, switch method { case .initiateSDK: trueSdk.delegate = self + trueSdk.viewDelegate = controller result(true) case .isUsable: result(trueSdk.isSupported()) + case .requestVerification: + requestVerification(call: call, + result: result) + result(true) + case .verifyOtp: + verifyOtpAndName(call: call, + result: result) case .setDarkTheme, .setLocale, - .requestVerification, - .verifyOtp, .verifyMissedCall: result(Constants.Error.methodNotImplemented) + result(true) case .getProfile: trueSdk.requestTrueProfile() + result(true) case .none: result(Constants.Error.methodNotImplemented) } } + + private func requestVerification(call: FlutterMethodCall, + result: @escaping FlutterResult) { + switch getVerificationArguments(from: call) { + case .success(let arguments): + trueSdk.requestVerification(forPhone: arguments.phoneNumber, + countryCode: arguments.isoCountryCode) + case .failure(let error): + result(error) + } + } + + private typealias VerificationArguments = (phoneNumber: String, isoCountryCode: String) + + private func getVerificationArguments(from call: FlutterMethodCall) -> Result { + guard let arguments = call.arguments as? [String: Any] else { + return .failure(TCError(code: TCTrueSDKErrorCode.badRequest, + description: Constants.ErrorDescription.unableToParseArguments)) + } + guard let phone = arguments[Constants.Arguments.phone] as? String else { + return .failure(TCError(code: TCTrueSDKErrorCode.badRequest, + description: Constants.ErrorDescription.phoneNumberEmpty)) + } + + let countryCode = arguments[Constants.Arguments.countryCode] as? String + ?? Constants.CountryCode.india + return .success((phone,countryCode)) + } + + private func verifyOtpAndName(call: FlutterMethodCall, + result: @escaping FlutterResult) { + switch getCodeAndNames(from: call) { + case .success(let arguments): + trueSdk.verifySecurityCode(arguments.code, + andUpdateFirstname: arguments.firstName, + lastName: arguments.lastname) + case .failure(let error): + result(error) + } + } + + private typealias CodeAndName = (firstName: String, lastname: String, code: String) + + private func getCodeAndNames(from call: FlutterMethodCall) -> Result { + guard let arguments = call.arguments as? [String: Any] else { + return .failure(TCError(code: TCTrueSDKErrorCode.badRequest, + description: Constants.ErrorDescription.unableToParseArguments)) + } + guard let code = arguments[Constants.Arguments.otp] as? String else { + return .failure(TCError(code: TCTrueSDKErrorCode.badRequest, + description: Constants.ErrorDescription.otpEmpty)) + } + + guard let firstName = arguments[Constants.Arguments.firstName] as? String else { + return .failure(TCError(code: TCTrueSDKErrorCode.badRequest, + description: Constants.ErrorDescription.firstNameEmpty)) + } + + let lastName = arguments[Constants.Arguments.lastName] as? String ?? "" + return .success((firstName, lastName, code)) + } } // MARK: - App delegate methods - @@ -124,6 +198,23 @@ extension SwiftTruecallerSdkPlugin: TCTrueSDKDelegate { eventSink?(map) } + public func verificationStatusChanged(to verificationState: TCVerificationState) { + var map = [String: Any]() + map[Constants.String.result] = verificationState.rawValue + switch verificationState { + case .otpInitiated: + map[Constants.String.data] = trueSdk.tokenTtl() + case .otpReceived, + .verifiedBefore: + break + case .verificationComplete: + map[Constants.String.data] = trueSdk.accessTokenForOTPVerification + @unknown default: + break + } + eventSink?(map) + } + public func didReceive(_ profileResponse: TCTrueProfileResponse) { trueProfileResponse = profileResponse } @@ -133,6 +224,6 @@ extension SwiftTruecallerSdkPlugin: TCTrueSDKDelegate { map[Constants.String.result] = Constants.String.failure map[Constants.String.data] = error.toDict.tojsonString trueProfileResponse = nil - eventSink?(error) + eventSink?(map) } }