我创建了这个AllInOneSDKSwiftWrapper.swift类,然后xcode在添加了paytm doc中给出的代码后要求我提供桥接标头,它在文件中给出了多个错误。我还添加了AllInOneSDKSwiftWrapper.m文件。我不是ios开发人员,所以我不知道如何解决,应该在空的生成的桥接头文件中写什么。
答案 0 :(得分:1)
Paytm对iOS和Android的本机支持文档反应非常差,因为它不具备在本机端设置和运行代码所需的全部信息。
以下是运行 Xcode v12.0 , Swift 5 , RN v0.63.2
的iOS实现。将框架复制并粘贴到“ ios / YourApp ”文件夹中
打开工作区,然后单击文件->添加文件
导航到框架,选择它,然后单击“添加”。(这很重要,请不要按照Paytm文档中的说明进行拖放)
在“常规”标签下的 TARGETS / YourApp 中,框架应在框架,库和嵌入式内容
部分中链接将“嵌入”选项更改为嵌入并签名
在 PROJECT-> YourApp->构建设置中添加以下路径链接。搜索标题搜索路径,然后添加以下路径
$(SRCROOT)/../ node_modules / react-native / Libraries / LinkingIOS
在 Bridging-Header.h
中导入标题#import "React/RCTBridgeModule.h"
#import "React/RCTEventEmitter.h"
AllInOneSDKSwiftWrapper.h
#import <Foundation/Foundation.h>
#import "React/RCTBridgeModule.h"
#if __has_include("RCTEventEmitter.h")
#import "RCTEventEmitter.h"
#else
#import <React/RCTEventEmitter.h>
#endif
@interface RCT_EXTERN_MODULE(AllInOneSDKSwiftWrapper, RCTEventEmitter)
RCT_EXTERN_METHOD(openPaytm:(NSString *)mid
orderId:(NSString *)oid
transactionToken:(NSString *)txnTkn
amount:(NSString *)amt
callbackUrl:(NSString *)url
isStaging: (BOOL)isStaging)
@end
AllInOneSDKSwiftWrapper.swift
import Foundation
import AppInvokeSDK
import UIKit
class EventEmitter {
/// Shared Instance.
public static var sharedInstance = EventEmitter()
// ReactNativeEventEmitter is instantiated by React Native with the bridge.
private static var eventEmitter: AllInOneSDKSwiftWrapper!
private init() {}
// When React Native instantiates the emitter it is registered here.
func registerEventEmitter(eventEmitter: AllInOneSDKSwiftWrapper) {
EventEmitter.eventEmitter = eventEmitter
}
func dispatch(name: String, body: Any?) {
EventEmitter.eventEmitter.sendEvent(withName: name, body: body)
}
/// All Events which must be support by React Native.
lazy var allEvents: [String] = {
var allEventNames: [String] = ["responseIfNotInstalled", "responseIfPaytmInstalled"]
// Append all events here
return allEventNames
}()
}
@objc(AllInOneSDKSwiftWrapper)
class AllInOneSDKSwiftWrapper: RCTEventEmitter, AIDelegate {
private let handler = AIHandler()
var viewController = UIApplication.shared.windows.first?.rootViewController
override static func moduleName() -> String! {
return "AllInOneSDKSwiftWrapper"
}
override init() {
super.init()
EventEmitter.sharedInstance.registerEventEmitter(eventEmitter: self)
NotificationCenter.default.addObserver(self, selector: #selector(getAppInvokeResponse(notification:)), name: NSNotification.Name(rawValue: "appInvokeNotification"), object: nil)
}
@objc func getAppInvokeResponse(notification: NSNotification) {
if let userInfo = notification.userInfo {
let url = userInfo["appInvokeNotificationKey"] as? String
let response = self.separateDeeplinkParamsIn(url: url, byRemovingParams: nil)
let alert = UIAlertController(title: "Response", message: response.description, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel, handler: nil))
self.viewController?.present(alert, animated: true, completion: nil)
sendEvent(withName: "responseIfPaytmInstalled", body: response)
}
}
/// Base overide for RCTEventEmitter.
///
/// - Returns: all supported events
@objc open override func supportedEvents() -> [String] {
return EventEmitter.sharedInstance.allEvents
}
@objc override static func requiresMainQueueSetup() -> Bool {
return true
}
@objc(openPaytm:orderId:transactionToken:amount:callbackUrl:isStaging:)
func openPaytm(_ mid: String, orderId: String, transactionToken: String, amount: String, callbackUrl: String?, isStaging: Bool) {
DispatchQueue.main.async {
var env:AIEnvironment = .production
if isStaging {
env = .staging
} else {
env = .production
}
self.handler.openPaytm(merchantId: mid, orderId: orderId, txnToken: transactionToken, amount: amount, callbackUrl: callbackUrl, delegate: self, environment: env)
}
}
@objc func separateDeeplinkParamsIn(url: String?, byRemovingParams rparams: [String]?) -> [String: String] {
guard let url = url else {
return [String : String]()
}
/// This url gets mutated until the end. The approach is working fine in current scenario. May need a revisit.
var urlString = stringByRemovingDeeplinkSymbolsIn(url: url)
var paramList = [String : String]()
let pList = urlString.components(separatedBy: CharacterSet.init(charactersIn: "&?"))
for keyvaluePair in pList {
let info = keyvaluePair.components(separatedBy: CharacterSet.init(charactersIn: "="))
if let fst = info.first , let lst = info.last, info.count == 2 {
paramList[fst] = lst.removingPercentEncoding
if let rparams = rparams, rparams.contains(info.first!) {
urlString = urlString.replacingOccurrences(of: keyvaluePair + "&", with: "")
//Please dont interchage the order
urlString = urlString.replacingOccurrences(of: keyvaluePair, with: "")
}
}
}
if let trimmedURL = pList.first {
paramList["trimmedurl"] = trimmedURL
}
return paramList
}
func stringByRemovingDeeplinkSymbolsIn(url: String) -> String {
var urlString = url.replacingOccurrences(of: "$", with: "&")
// This may need a revisit. This is doing more than just removing the deeplink symbol.
if let range = urlString.range(of: "&"), urlString.contains("?") == false {
urlString = urlString.replacingCharacters(in: range, with: "?")
}
return urlString
}
func openPaymentWebVC(_ controller: UIViewController?) {
if let vc = controller {
DispatchQueue.main.async {[weak self] in self?.viewController?.present(vc, animated: true, completion: nil)}
}
}
func didFinish(with status: AIPaymentStatus, response: [String : Any]) {
sendEvent(withName: "responseIfNotInstalled", body: response)
let alert = UIAlertController(title: "(status)", message: String(describing: response), preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
DispatchQueue.main.async { self.viewController?.present(alert, animated: true, completion: nil) }
}
}
AppDelegate.m
#import "RCTLinkingManager.h" // Import this header
// Add the below function
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
NSString *urlString = url.absoluteString;
NSDictionary *userInfo =
[NSDictionary dictionaryWithObject:urlString forKey:@"appInvokeNotificationKey"];
[[NSNotificationCenter defaultCenter] postNotificationName:@"appInvokeNotification" object:nil userInfo:userInfo];
return [RCTLinkingManager application:app openURL:url options:options];
}
PaytmT.ts
import { NativeModules, NativeEventEmitter, Alert } from 'react-native'
export class PaytmT {
/** Call this function to invoke the Paytm Flow for iOS */
invoke() {
const allInOnePaytmSDK = NativeModules.AllInOneSDKSwiftWrapper
allInOnePaytmSDK.openPaytm('MERCHANT_ID', 'ORDER_ID', 'TXN_TOKEN', 'AMOUNT', 'CALLBACKURL', true) // If production environment, change it to false
const CounterEvents = new NativeEventEmitter(NativeModules.AllInOneSDKSwiftWrapper)
CounterEvents.addListener('responseIfNotInstalled', (response) => {
Alert.alert(PaytmT.name, JSON.stringify(response))
})
CounterEvents.addListener('responseIfPaytmInstalled', (response) => {
Alert.alert(PaytmT.name, JSON.stringify(response))
})
}
}