Commit 7998a3e1 authored by Javohir Savriy's avatar Javohir Savriy
Browse files

Add iOS module

parent 52262fce
import Foundation
// import Onfido
//
// public class AppearancePublic: NSObject {
//
// public let primaryColor: UIColor
// public let primaryTitleColor: UIColor
// public let primaryBackgroundPressedColor: UIColor
// public let supportDarkMode: Bool
//
// public init(
// primaryColor: UIColor,
// primaryTitleColor: UIColor,
// primaryBackgroundPressedColor: UIColor,
// supportDarkMode: Bool = true) {
// self.primaryColor = primaryColor
// self.primaryTitleColor = primaryTitleColor
// self.primaryBackgroundPressedColor = primaryBackgroundPressedColor
// self.supportDarkMode = supportDarkMode
// }
// }
//
// public func loadAppearance(config: NSDictionary) throws -> AppearancePublic? {
//
// if let jsonResult = config as? Dictionary<String, AnyObject> {
// let primaryColor: UIColor = (jsonResult["onfidoPrimaryColor"] == nil)
// ? UIColor.primaryColor : UIColor.from(hex: jsonResult["onfidoPrimaryColor"] as! String)
// let primaryTitleColor: UIColor = (jsonResult["onfidoPrimaryButtonTextColor"] == nil)
// ? UIColor.white : UIColor.from(hex: jsonResult["onfidoPrimaryButtonTextColor"] as! String)
// let primaryBackgroundPressedColor: UIColor = (jsonResult["onfidoPrimaryButtonColorPressed"] == nil)
// ? UIColor.primaryButtonColorPressed : UIColor.from(hex: jsonResult["onfidoPrimaryButtonColorPressed"] as! String)
// let supportDarkMode: Bool = (jsonResult["onfidoIosSupportDarkMode"] == nil)
// ? true : jsonResult["onfidoIosSupportDarkMode"] as! Bool
//
//
// let appearancePublic = AppearancePublic(
// primaryColor: primaryColor,
// primaryTitleColor: primaryTitleColor,
// primaryBackgroundPressedColor: primaryBackgroundPressedColor,
// supportDarkMode: supportDarkMode
// )
// return appearancePublic
// } else {
// return nil
// }
// }
//
// public func loadAppearanceFromConfig(config: NSDictionary) throws -> Appearance {
// let appearancePublic = try loadAppearance(config: config)
//
// if let appearancePublic = appearancePublic {
// return Appearance(
// primaryColor: appearancePublic.primaryColor,
// primaryTitleColor: appearancePublic.primaryTitleColor,
// primaryBackgroundPressedColor: appearancePublic.primaryBackgroundPressedColor,
// supportDarkMode: appearancePublic.supportDarkMode
// )
// } else {
// return Appearance.default;
// }
// }
//
// public func buildOnfidoConfig(config:NSDictionary, appearance: Appearance) throws -> Onfido.OnfidoConfigBuilder {
// let sdkToken:String = config["sdkToken"] as! String
// let flowSteps:NSDictionary? = config["flowSteps"] as? NSDictionary
// let captureDocument:NSDictionary? = flowSteps?["captureDocument"] as? NSDictionary
// let captureFace:NSDictionary? = flowSteps?["captureFace"] as? NSDictionary
//
// var onfidoConfig = OnfidoConfig.builder()
// .withSDKToken(sdkToken)
// .withAppearance(appearance)
//
//
// if flowSteps?["welcome"] as? Bool == true {
// onfidoConfig = onfidoConfig.withWelcomeStep()
// }
//
// if let docType = captureDocument?["docType"] as? String, let countryCode = captureDocument?["countryCode"] as? String {
// switch docType {
// case "PASSPORT":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .passport(config: PassportConfiguration()))
// case "DRIVING_LICENCE":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .drivingLicence(config: DrivingLicenceConfiguration(country: countryCode)))
// case "NATIONAL_IDENTITY_CARD":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .nationalIdentityCard(config: NationalIdentityConfiguration(country: countryCode)))
// case "RESIDENCE_PERMIT":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .residencePermit(config: ResidencePermitConfiguration(country: countryCode)))
// case "VISA":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .visa(config: VisaConfiguration(country: countryCode)))
// case "WORK_PERMIT":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .workPermit(config: WorkPermitConfiguration(country: countryCode)))
// case "GENERIC":
// onfidoConfig = onfidoConfig.withDocumentStep(ofType: .generic(config: GenericDocumentConfiguration(country: countryCode)))
// default:
// throw NSError(domain: "Unsupported document type", code: 0)
// }
// } else if captureDocument != nil {
// onfidoConfig = onfidoConfig.withDocumentStep()
// }
//
// if let faceVariant = captureFace?["type"] as? String {
// if faceVariant == "VIDEO" {
// onfidoConfig = onfidoConfig.withFaceStep(ofVariant: .video(withConfiguration: VideoStepConfiguration(showIntroVideo: true, manualLivenessCapture: false)))
// } else if faceVariant == "PHOTO" {
// onfidoConfig = onfidoConfig.withFaceStep(ofVariant: .photo(withConfiguration: nil))
// } else {
// throw NSError(domain: "Invalid or unsupported face variant", code: 0)
// }
// }
// return onfidoConfig;
// }
//
// @objc(OnfidoSdk)
// class OnfidoSdk: NSObject {
//
// @objc static func requiresMainQueueSetup() -> Bool {
// return false
// }
//
// @objc func start(_ config: NSDictionary, result: @escaping FlutterResult) -> Void {
// DispatchQueue.main.async {
// let withConfig = config["config"] as! NSDictionary
// let withAppearance = config["appearance"] as! NSDictionary
// self.run(withConfig: withConfig, withAppearance: withAppearance, result: result)
// }
// }
//
// private func run(withConfig config: NSDictionary, withAppearance appearanceConfig: NSDictionary, result: @escaping FlutterResult) {
//
// do {
// let appearance = try loadAppearanceFromConfig(config: appearanceConfig)
// let onfidoConfig = try buildOnfidoConfig(config: config, appearance: appearance)
// let builtOnfidoConfig = try onfidoConfig.build()
//
// // Copy the face varient from the config since it is not contained in the response:
// let flowSteps:NSDictionary? = config["flowSteps"] as? NSDictionary
// let captureFace:NSDictionary? = flowSteps?["captureFace"] as? NSDictionary
// let faceVariant = captureFace?["type"] as? String
//
// let onfidoFlow = OnfidoFlow(withConfiguration: builtOnfidoConfig)
// .with(responseHandler: { [weak self] response in
// guard let `self` = self else { return }
// switch response {
// case let .error(error):
// result(FlutterError(code: "error", message: "Encountered an error: \(error)", details: nil))
// return;
// case let .success(results):
// result(createResponse(results, faceVariant: faceVariant))
// return;
// case .cancel:
// result(FlutterError(code: "cancel", message: "User canceled flow", details: nil))
// return;
// default:
// result(FlutterError(code: "error", message: "Unknown error has occured", details: nil))
// return;
// }
// })
//
// let onfidoRun = try onfidoFlow.run()
// UIApplication.shared.windows.first?.rootViewController?.present(onfidoRun, animated: true)
// } catch let error as NSError {
// result(FlutterError(code: "error", message: error.domain, details: nil))
// return;
// } catch {
// result(FlutterError(code: "error", message: "Error running Onfido SDK", details: nil))
// return;
// }
// }
// }
//
// extension UIColor {
//
// static var primaryColor: UIColor {
// return decideColor(light: UIColor.from(hex: "#353FF4"), dark: UIColor.from(hex: "#3B43D8"))
// }
//
// static var primaryButtonColorPressed: UIColor {
// return decideColor(light: UIColor.from(hex: "#232AAD"), dark: UIColor.from(hex: "#5C6CFF"))
// }
//
// private static func decideColor(light: UIColor, dark: UIColor) -> UIColor {
// #if XCODE11
// guard #available(iOS 13.0, *) else {
// return light
// }
// return UIColor { (collection) -> UIColor in
// return collection.userInterfaceStyle == .dark ? dark : light
// }
// #else
// return light
// #endif
// }
//
// static func from(hex: String) -> UIColor {
//
// let hexString = hex.trimmingCharacters(in: .whitespacesAndNewlines)
// let scanner = Scanner(string: hexString)
//
// if hexString.hasPrefix("#") {
// scanner.scanLocation = 1
// }
//
// var color: UInt32 = 0
// scanner.scanHexInt32(&color)
//
// let mask = 0x000000FF
// let redInt = Int(color >> 16) & mask
// let greenInt = Int(color >> 8) & mask
// let blueInt = Int(color) & mask
//
// let red = CGFloat(redInt) / 255.0
// let green = CGFloat(greenInt) / 255.0
// let blue = CGFloat(blueInt) / 255.0
//
// return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
// }
// }
//
// extension Appearance {
//
// static let `default` = Appearance(
// primaryColor: UIColor.primaryColor,
// primaryTitleColor: UIColor.white,
// primaryBackgroundPressedColor: UIColor.primaryButtonColorPressed)
// }
import MyIdSDK
public class AppearancePublic: NSObject {
public let primaryColor: UIColor?
public let secondaryColor: UIColor?
public let errorColor: UIColor?
public let primaryButtonColor: UIColor?
public let primaryButtonColorDisabled: UIColor?
public let primaryButtonTextColor: UIColor?
public let primaryButtonTextColorDisabled: UIColor?
public let buttonCornerRadius: Int?
public init(
primaryColor: UIColor?,
secondaryColor: UIColor?,
errorColor: UIColor?,
primaryButtonColor: UIColor?,
primaryButtonColorDisabled: UIColor?,
primaryButtonTextColor: UIColor?,
primaryButtonTextColorDisabled: UIColor?,
buttonCornerRadius: Int?
) {
self.primaryColor = primaryColor
self.secondaryColor = secondaryColor
self.errorColor = errorColor
self.primaryButtonColor = primaryButtonColor
self.primaryButtonColorDisabled = primaryButtonColorDisabled
self.primaryButtonTextColor = primaryButtonTextColor
self.primaryButtonTextColorDisabled = primaryButtonTextColorDisabled
self.buttonCornerRadius = buttonCornerRadius
}
}
public func loadAppearance(config: NSDictionary) throws -> AppearancePublic? {
if let jsonResult = config as? Dictionary<String, AnyObject> {
let primaryColor = (jsonResult["primaryColor"] == nil)
? nil : UIColor.from(hex: jsonResult["primaryColor"] as! String)
let secondaryColor = (jsonResult["secondaryColor"] == nil)
? nil : UIColor.from(hex: jsonResult["secondaryColor"] as! String)
let errorColor = (jsonResult["errorColor"] == nil)
? nil : UIColor.from(hex: jsonResult["errorColor"] as! String)
let primaryButtonColor = (jsonResult["primaryButtonColor"] == nil)
? nil : UIColor.from(hex: jsonResult["primaryButtonColor"] as! String)
let primaryButtonColorDisabled = (jsonResult["primaryButtonColorDisabled"] == nil)
? nil : UIColor.from(hex: jsonResult["primaryButtonColorDisabled"] as! String)
let primaryButtonTextColor = (jsonResult["primaryButtonTextColor"] == nil)
? nil : UIColor.from(hex: jsonResult["primaryButtonTextColor"] as! String)
let primaryButtonTextColorDisabled = (jsonResult["primaryButtonTextColorDisabled"] == nil)
? nil : UIColor.from(hex: jsonResult["primaryButtonTextColorDisabled"] as! String)
let buttonCornerRadius: Int? = (jsonResult["buttonCornerRadius"] == nil) ? nil : 8
let appearancePublic = AppearancePublic(
primaryColor: primaryColor,
secondaryColor: secondaryColor,
errorColor: errorColor,
primaryButtonColor: primaryButtonColor,
primaryButtonColorDisabled: primaryButtonColorDisabled,
primaryButtonTextColor: primaryButtonTextColor,
primaryButtonTextColorDisabled: primaryButtonTextColorDisabled,
buttonCornerRadius: buttonCornerRadius
)
return appearancePublic
} else {
return nil
}
}
public func loadAppearanceFromConfig(config: NSDictionary) throws -> MyIdAppearance {
let appearancePublic = try loadAppearance(config: config)
if let appearancePublic = appearancePublic {
let appearance = MyIdAppearance()
appearance.primaryColor = appearancePublic.primaryColor
appearance.secondaryColor = appearancePublic.secondaryColor
appearance.errorColor = appearancePublic.errorColor
appearance.primaryButtonColor = appearancePublic.primaryButtonColor
appearance.primaryButtonColorDisabled = appearancePublic.primaryButtonColorDisabled
appearance.primaryButtonTextColor = appearancePublic.primaryButtonTextColor
appearance.primaryButtonTextColorDisabled = appearancePublic.primaryButtonTextColorDisabled
if let buttonCornerRadius = appearancePublic.buttonCornerRadius {
appearance.buttonCornerRadius = Float(buttonCornerRadius)
}
return appearance
} else {
return MyIdAppearance()
}
}
public func buildMyIdConfig(
config: NSDictionary,
appearance: MyIdAppearance
) throws -> MyIdConfig {
let clientId = config["clientId"] as? String ?? ""
let passportData = config["passportData"] as? String ?? ""
let dateOfBirth = config["dateOfBirth"] as? String ?? ""
let sdkHash = config["sdkHash"] as? String ?? ""
let externalId = config["externalId"] as? String ?? ""
let threshold = config["threshold"] as? Float ?? 0.6
let buildModeKey = config["buildMode"] as? String ?? ""
var buildMode = MyIdBuildMode.PRODUCTION
if (buildModeKey == "DEBUG") {
buildMode = MyIdBuildMode.DEBUG
}
let entryTypeKey = config["entryType"] as? String ?? ""
var entryType = MyIdEntryType.AUTH
if (entryTypeKey == "FACE") {
entryType = MyIdEntryType.FACE
}
let residencyKey = config["residency"] as? String ?? ""
var residency = MyIdResidency.RESIDENT
if (residencyKey == "USER_DEFINED") {
residency = MyIdResidency.USER_DEFINED
} else if (residencyKey == "NON_RESIDENT") {
residency = MyIdResidency.NON_RESIDENT
}
let localeKey = config["locale"] as? String ?? ""
var locale = MyIdLocale.UZ
if (localeKey == "RUS") {
locale = MyIdLocale.UZ
} else if (localeKey == "ENG") {
locale = MyIdLocale.EN
}
let cameraShapeKey = config["cameraShape"] as? String ?? ""
var cameraShape = MyIdCameraShape.CIRCLE
if (cameraShapeKey == "ELLIPSE") {
cameraShape = MyIdCameraShape.ELLIPSE
}
let resolutionKey = config["resolution"] as? String ?? ""
var resolution = MyIdResolution.RESOLUTION_480
if (resolutionKey == "RESOLUTION_720") {
resolution = MyIdResolution.RESOLUTION_720
}
let withPhoto = config["withPhoto"] as? Bool ?? false
let organizationDetailsDict = config["organizationDetails"] as? NSDictionary
let organizationDetails = MyIdOrganizationDetails()
organizationDetails.phoneNumber = organizationDetailsDict?["phone"] as? String ?? ""
let config = MyIdConfig()
config.clientId = clientId
config.passportData = passportData
config.dateOfBirth = dateOfBirth
config.sdkHash = sdkHash
config.externalId = externalId
config.threshold = threshold
config.buildMode = buildMode
config.entryType = entryType
config.residency = residency
config.locale = locale
config.cameraShape = cameraShape
config.resolution = resolution
config.withPhoto = withPhoto
config.appearance = appearance
config.organizationDetails = organizationDetails
return config
}
@objc(MyIdSdk)
class MyIdSdk: NSObject, MyIdClientDelegate {
private var flutterResult: FlutterResult? = nil
func onSuccess(result: MyIdResult) {
if let fResult = flutterResult {
fResult(createResponse(result))
}
}
func onError(exception: MyIdException) {
if let fResult = flutterResult {
fResult(FlutterError(code: "error", message: "\(exception.code ?? "101") - \(exception.message ?? "Unexpected error starting MyID")", details: nil))
}
}
func onUserExited() {
if let fResult = flutterResult {
fResult(FlutterError(code: "cancel", message: "User canceled flow", details: nil))
}
}
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func start(
_ config: NSDictionary,
result: @escaping FlutterResult
) -> Void {
flutterResult = result
DispatchQueue.main.async {
let withConfig = config["config"] as! NSDictionary
let withAppearance = config["appearance"] as! NSDictionary
self.run(withConfig: withConfig, withAppearance: withAppearance, result: result)
}
}
private func run(
withConfig config: NSDictionary,
withAppearance appearanceConfig: NSDictionary,
result: @escaping FlutterResult
) {
do {
let appearance = try loadAppearanceFromConfig(config: appearanceConfig)
let myidConfig = try buildMyIdConfig(config: config, appearance: appearance)
MyIdClient.start(withConfig: myidConfig, withDelegate: self)
} catch let error as NSError {
result(FlutterError(code: "error", message: error.domain, details: nil))
return;
} catch {
result(FlutterError(code: "error", message: "Unexpected error starting MyID", details: nil))
return;
}
}
}
extension UIColor {
static func from(hex: String) -> UIColor {
let hexString = hex.trimmingCharacters(in: .whitespacesAndNewlines)
let scanner = Scanner(string: hexString)
if hexString.hasPrefix("#") {
scanner.scanLocation = 1
}
var color: UInt32 = 0
scanner.scanHexInt32(&color)
let mask = 0x000000FF
let redInt = Int(color >> 16) & mask
let greenInt = Int(color >> 8) & mask
let blueInt = Int(color) & mask
let red = CGFloat(redInt) / 255.0
let green = CGFloat(greenInt) / 255.0
let blue = CGFloat(blueInt) / 255.0
return UIColor(red: red, green: green, blue: blue, alpha: 1.0)
}
}
extension MyIdAppearance {
static let `default` = MyIdAppearance()
}
import Foundation
// import Onfido
//
// func createResponse(_ results: [OnfidoResult], faceVariant: String?) -> [String: [String: Any]] {
// var jsonResponse = [String: [String: Any]]()
//
// let document: [OnfidoResult]? = results.filter({ result in
// if case OnfidoResult.document = result { return true }
// return false;
// });
//
// let onfidoResult: OnfidoResult? = document?.first
//
// let face: OnfidoResult? = results.filter({ result in
// if case OnfidoResult.face = result { return true }
// return false
// }).first
//
// if let documentUnwrapped = onfidoResult, case OnfidoResult.document(let documentResponse) = documentUnwrapped {
// jsonResponse["document"] = ["front": ["id": documentResponse.front.id]]
//
// if let back = documentResponse.back {
// jsonResponse["document"]?["back"] = ["id": back.id]
// }
// }
//
// if let faceUnwrapped = face, case OnfidoResult.face(let faceResponse) = faceUnwrapped {
// jsonResponse["face"] = ["id": faceResponse.id, "variant": faceVariant!]
// }
//
// return jsonResponse
// }
import MyIdSDK
func createResponse(_ result: MyIdResult) -> [String: String] {
var jsonResponse = [String: String]()
if let code = result.code {
jsonResponse["code"] = code
}
if let comparison = result.comparisonValue {
jsonResponse["comparison"] = comparison
}
if let image = result.image {
if let base64 = image.jpegData(compressionQuality: 1.0)?.base64EncodedString() {
jsonResponse["base64"] = base64
}
}
return jsonResponse
}
......@@ -3,6 +3,8 @@ import UIKit
public class SwiftMyIdPlugin: NSObject, FlutterPlugin {
private let myidSdk = MyIdSdk()
public static func register(with registrar: FlutterPluginRegistrar) {
let channel = FlutterMethodChannel(name: "myid", binaryMessenger: registrar.messenger())
let instance = SwiftMyIdPlugin()
......@@ -10,24 +12,9 @@ public class SwiftMyIdPlugin: NSObject, FlutterPlugin {
}
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
result("iOS " + UIDevice.current.systemVersion)
if(call.method.elementsEqual("startSdk")){
let config = call.arguments as! NSDictionary
myidSdk.start(config, result: result)
}
}
}
// @available(iOS 11.0, *)
// public class SwiftFlutterOnfidoPlugin: NSObject, FlutterPlugin {
// private let onfidoSdk = OnfidoSdk()
//
// public static func register(with registrar: FlutterPluginRegistrar) {
// let channel = FlutterMethodChannel(name: "flutter_onfido", binaryMessenger: registrar.messenger())
// let instance = SwiftFlutterOnfidoPlugin()
// registrar.addMethodCallDelegate(instance, channel: channel)
// }
//
// public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
// if(call.method.elementsEqual("start")){
// let config = call.arguments as! NSDictionary
// onfidoSdk.start(config, result: result)
// }
// }
// }
......@@ -5,19 +5,20 @@
Pod::Spec.new do |s|
s.name = 'myid'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin project.'
s.summary = 'A new Flutter plugin.'
s.description = <<-DESC
A new Flutter plugin project.
A new Flutter plugin.
DESC
s.homepage = 'http://example.com'
s.homepage = 'https://pub.dev/packages/myid'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.dependency 'Flutter'
s.platform = :ios, '9.0'
s.dependency 'MyId'
s.platform = :ios, '11.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
# Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
s.swift_version = '5.0'
end
......@@ -2,7 +2,7 @@ name: myid
description: MyID SDK plugin for Flutter. Package supports iOS and Android to verify users identity.
version: 1.0.5
homepage: https://pub.dev/packages/myid
repository: https://gitlab.myid.uz/myid/mobile/myid-sample-flutter
repository: https://pub.dev/packages/myid
issue_tracker: https://gitlab.myid.uz/myid/mobile/myid-sample-flutter/-/issues
environment:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment