Работа с нативной частью SDK
iOS
В проекте Runner.xcodeproj
перейдите в файл AppDelegate
Импортируйте модуль import SPaySdk
В методе:
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
Вам необходимо определить название канала для установки связи через MethodChannel
:
let sdk_channel_name = "com.spay.sdk/pay"
В том же методе необходимо определить контроллер, для передачи в канал и сам канал:
let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
let sdkChannel = FlutterMethodChannel(name: sdk_channel_name,
binaryMessenger: controller.binaryMessenger)
далее в том же методе вызовите:
sdkChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in {
switch call.method {
case "isReadyForSPay":
result(SPay.isReadyForSPay)
default:
result(FlutterMethodNotImplemented)
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
в completion блоке метода Вам необходимо будет определить switch со всеми методами sdk из раздела Документация iOS SDK для разработчиков
с которыми Вам предстоит работать.
Подключение нативной кнопки оплаты
В методе didFinishLaunchingWithOptions
в файле AppDelegate
необходимо определить плагин:
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
...
GeneratedPluginRegistrant.register(with: self)
weak var registrar = self.registrar(forPlugin: "plugin-name")
let factory = FLNativeViewFactory(messenger: registrar!.messenger())
self.registrar(forPlugin: "<plugin-name>")!.register(
factory,
withId: "<platform-view-type>")
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
Внутри проекта Runner
создайте папку FLPlugin
и поместите в нее одноименный файл.
Внутри файла поместите следующий код:
import Flutter
import UIKit
class FLPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
let factory = FLNativeViewFactory(messenger: registrar.messenger())
registrar.register(factory, withId: "<platform-view-type>")
}
}
Внутри проекта Runner
создайте папку FLNativeViewFactory
и поместите в нее одноименный файл.
Внутри файла поместите следующий код, который поможет использовать кнопку SberPay SDK:
import Flutter
import UIKit
import SPaySdk
class FLNativeViewFactory: NSObject, FlutterPlatformViewFactory {
private var messenger: FlutterBinaryMessenger
init(messenger: FlutterBinaryMessenger) {
self.messenger = messenger
super.init()
}
func create(
withFrame frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?
) -> FlutterPlatformView {
return FLNativeSPayButtonView(
frame: frame,
viewIdentifier: viewId,
arguments: args,
binaryMessenger: messenger)
}
public func createArgsCodec() -> FlutterMessageCodec & NSObjectProtocol {
return FlutterStandardMessageCodec.sharedInstance()
}
}
class FLNativeSPayButtonView: NSObject, FlutterPlatformView {
private var _view: UIView
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?
) {
_view = UIView()
super.init()
setupButton(view: _view)
}
func view() -> UIView {
return _view
}
func setupButton(view _view: UIView){
let button = SBPButton()
_view.addSubview(button)
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
button.topAnchor.constraint(equalTo: _view.topAnchor),
button.leadingAnchor.constraint(equalTo: _view.leadingAnchor),
button.trailingAnchor.constraint(equalTo: _view.trailingAnchor),
button.bottomAnchor.constraint(equalTo: _view.bottomAnchor)
])
}
}
Android
В Android части проекта найдите MainActivity.kt
В методе MainActivity
вставьте следующий код:
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.spay.sdk/pay"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
}
}
}
Нобходимо полное соответсвие названия канала в ios и android модулях.
Внутри метода MethodChannel
необходимо с помощью блоков if - else определить названия методов для sdk по аналогии с ios. Методы взаимодействия с sdk вы найдете в разделе Документация Android SDK для разработчиков
Пример:
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
call, result ->
if (call.method == "isReadyForSPay") {
val sPayButton = findViewById<SPayButton>(R.id.sPayButton)
result.success(sPayButton.isReadyForSPaySdk())
} else {
result.notImplemented()
}
}
Подключение нативной кнопки оплаты
Для взаимодействия UI-компонентов необходимо в Android директории проекта создать файл NativeView
и внутри файла разместить следующий код:
package dev.flutter.example
import android.content.Context
import android.graphics.Color
import android.view.View
import android.widget.TextView
import io.flutter.plugin.platform.PlatformView
internal class NativeView(context: Context, id: Int, creationParams: Map<String?, Any?>?) : PlatformView {
private val button: SberPayButton
override fun getView(): View {
return button
}
override fun dispose() {}
init {
button = SberPayButton(context, attributeSet = null)
}
}
package dev.flutter.plugin.example
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.FlutterPlugin.FlutterPluginBinding
class PlatformViewPlugin : FlutterPlugin {
override fun onAttachedToEngine(binding: FlutterPluginBinding) {
binding
.platformViewRegistry
.registerViewFactory("<platform-view-type>", NativeViewFactory())
}
override fun onDetachedFromEngine(binding: FlutterPluginBinding) {}
}
В Android директории проекта создайте файл NativeViewFactory
и внутри файла размиестить следующий код:
package dev.flutter.example
import android.content.Context
import io.flutter.plugin.common.StandardMessageCodec
import io.flutter.plugin.platform.PlatformView
import io.flutter.plugin.platform.PlatformViewFactory
class NativeViewFactory : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
val creationParams = args as Map<String?, Any?>?
return NativeView(context, viewId, creationParams)
}
}
В файле MainActivity.kt
необходимо реализовать следующие функции для связи нативных UI представлений с Flutter
package dev.flutter.example
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
class MainActivity : FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
flutterEngine
.platformViewsController
.registry
.registerViewFactory("<platform-view-type>",
NativeViewFactory())
}
}