TapQRCode-iOS
一个提供生成和扫描不同类型二维码接口的 SDK。
要求
要使用 SDK,必须满足以下要求
- Xcode 11.0 或更高版本
- Swift 4.2 或更高版本(随 Xcode 预安装)
- 应用的部署目标 SDK:iOS 12.0 或更高版本
安装
使用 CocoaPods 安装
CocoaPods 是一个依赖关系管理器,它可以自动简化在项目中使用第三方库的过程。您可以使用以下命令安装它
$ gem install cocoapods
Podfile
要将 goSellSDK 集成到您的 Xcode 项目中并使用 CocoaPods,请在您的 Podfile
中指定它。
platform :ios, '12.0'
use_frameworks!
source 'https://github.com/CocoaPods/Specs.git'
target 'MyApp' do
pod 'TapQRCode-iOS'
end
然后,运行以下命令
$ pod update
功能
TapQRCode-iOS
提供了生成和扫描二维码的广泛方式,使它成为市场上最具包容性的 pod 之一,同时也是最易于集成的。
生成二维码
您可以使用相同的界面生成不同类型的二维码,包括
- 基于文本的二维码。
- 基于 URL 的二维码。
- 基于 EMVCO 推付款的二维码。
此外,TapQRCodeGenerator
提供了一个接口来按以下方式样式化生成的二维码
- 前景色。
- 背景色。
- 中心图标。
扫描二维码
您可以使用相同的界面从不同来源扫描不同类型的二维码,包括
- 在图像中扫描代码。
- 将扫描器作为 SubView 内联提供到您的 UIView 中。
- 显示全屏扫描器。
此外,TapQRCodeScanner
提供了一个接口来按以下方式样式化扫描器
- 显示像翻转相机和手电筒按钮这样的访问按钮。
- 手电筒按钮图标。
- 覆盖扫描框。
使用方法
本节描述了如何使用 SWIFT 和 Objective C 语言调用和初始化不同的生成器和扫描器。
生成二维码
以下介绍如何将特定主题文件附加到共享ThemeManager以及如何更改运行时的主题。
基于文本的QR码
TapQRCodeGenerator
可以生成以下纯文本形式的QR码
Swift:
import TapQRCode_iOS
let tapGeneratedQRImage:UIImage = TapQRCodeGenerator.generateQrCode(with: .init(withText: "Hello from Tap Payments"), foreGroundColor: .red, backgroundColor: .white, waterMark: UIImage(named: "Tap"))
Objective-C:
@import TapQRCode_iOS;
UIImage* tapGeneratedQRImage = [TapQRCodeGenerator generateQrCodeWith:[[TapQrCodeContent alloc]initWithText:@"Hello from Tap Payments"] foreGroundColor:UIColor.redColor backgroundColor:UIColor.whiteColor waterMark:[UIImage imageNamed:@"Tap"]];
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
qrCodeContent | TapQrCodeContent.init(withText) | 是 | 无 | 包含所需的二维码类型和内容的TapQrCodeContent |
foreGroundColor | UIColor | 否 | 黑色 | 二维码的国点颜色和方块颜色。 |
backgroundColor | UIColor | 否 | 清除 | 二维码的背景颜色。 |
waterMark | UIImage | 否 | 无 | 水印图像出现在二维码的中心。 |
基于URL的QR码
TapQRCodeGenerator
可以生成以下纯URL形式的QR码
Swift:
import TapQRCode_iOS
let tapGeneratedQRImage:UIImage = TapQRCodeGenerator.generateQrCode(with: .init(withUrl: URL(string: "https://tap.company")), foreGroundColor: .red, backgroundColor: .white, waterMark: UIImage(named: "Tap"))
Objective-C:
@import TapQRCode_iOS;
UIImage* tapGeneratedQRImage = [TapQRCodeGenerator generateQrCodeWith:[[TapQrCodeContent alloc]initWithUrl:[NSURL URLWithString:@"https://tap.company"]] foreGroundColor:UIColor.redColor backgroundColor:UIColor.whiteColor waterMark:[UIImage imageNamed:@"Tap"]];
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
qrCodeContent | TapQrCodeContent.init(withUrl) | 是 | 无 | 包含所需的二维码类型和内容的TapQrCodeContent |
foreGroundColor | UIColor | 否 | 黑色 | 二维码的国点颜色和方块颜色。 |
backgroundColor | UIColor | 否 | 清除 | 二维码的背景颜色。 |
waterMark | UIImage | 否 | 无 | 水印图像出现在二维码的中心。 |
基于EMVCO推送支付的QR码
TapQRCodeGenerator
可以生成包含EMVCO推送支付代码的QR码,该代码可以被任何可接受的EMVCO解析器读取,如下所示
Swift:
import TapQRCode_iOS
do {
let image = try TapQRCodeGenerator.generateQrCode(with: .init(withEmv:
TapEmvcoPushData(pointOfInitiation: .Dynamic,
merchantPaymentTags: [.init(with: .VisaTag02, value: "4600678934521435")],
transactionAmount: 10,
transactionCurrency: .KWD,
extraFeesMode: .FixedFees,
extraFeesAmount: 5,
countryCode: .KW,
merchantCategoryCode: "1171",
merchantName: "Tap Payments",
merchantCity: "Kuwait City",
postalCode: nil,
additionData: TapEmvcoAdditionalData(
billNumber: "Bill 123",
customerLabel: "Tap Customer",
loyaltyNumber: "123",
mobileNumber: "0096599999999",
purposeForTransaction: "Tap Transaction",
storeLabel: "Store 1",
terminalLabel: "Terminal 1",
additionalCustomerDataCollection: .addressPhone))))
}catch {
print(error.localizedDescription)
}
Objective-C:
@import TapQRCode_iOS;
NSError* error;
UIImage* tapGeneratedQRImage = [TapQRCodeGenerator generateQrCodeWith:[[TapQrCodeContent alloc]initWithEmv:[[TapEmvcoPushData alloc]
initWithPointOfInitiation:TapEmvcoOfInitiationDynamic
merchantPaymentTags:@[[[TapEmvcoPaymentNetwork alloc]initWith:TapEmvcoNetworkTagsVisaTag02 value:@"4600678934521435"]]
transactionAmount:10
transactionCurrency:TapEmvcoCurrencyCodeKWD
extraFeesMode:TapEmvcoExtraFeesFixedFees
extraFeesAmount:5
countryCode:TapEmvcoCountryCodeKW
merchantCategoryCode:@"1171"
merchantName:@"Tap Payments"
merchantCity:@"Kuwait City"
postalCode:nil
additionData:[[TapEmvcoAdditionalData alloc]
initWithBillNumber:@"123"
customerLabel:@"Tap Customer"
loyaltyNumber:@"123"
mobileNumber:@"0096599999999"
purposeForTransaction:@"Tap Transaction"
storeLabel:@"Store 1"
terminalLabel:@"Terminal 1"
additionalCustomerDataCollection:TapEmvcoAdditionalDataCollectionPhoneEmail]
error:&error]] foreGroundColor:UIColor.redColor backgroundColor:UIColor.whiteColor waterMark:[UIImage imageNamed:@"Tap"]];
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
qrCodeContent | TapQrCodeContent.init(initWithEmv) | 是 | 无 | 包含所需的二维码类型和内容的TapQrCodeContent。 要生成EMVCO推送支付,请参阅以下**TapEmvcoPushData、TapEmvcoPaymentNetwork和TapEmvcoAdditionalData**的参数 |
foreGroundColor | UIColor | 否 | 黑色 | 二维码的国点颜色和方块颜色。 |
backgroundColor | UIColor | 否 | 清除 | 二维码的背景颜色。 |
waterMark | UIImage | 否 | 无 | 水印图像出现在二维码的中心。 |
TapEmvcoPushData
此模型代表一个比标准EMVCO数据EMVCO数据更易理解和更易于使用的包装。我们希望提供一个接口,以便实体可以生成EMVCO接受的代码,而无需理解并阅读复杂的EMVCO标准。
使用直接数据初始化 TapEmvcoPushData
可以通过以下方式提供数据来初始化 TapEmvcoPushData
Swift:
import TapQRCode_iOS
do {
let tapEmvcoData:TapEmvcoPushData = try TapEmvcoPushData.init(
pointOfInitiation: .Dynamic,
merchantPaymentTags: [.init(with: .VisaTag02, value: "4600678934521435")],
transactionAmount: 10,
transactionCurrency: .KWD,
extraFeesMode: .FixedFees,
extraFeesAmount: 5,
countryCode: .KW,
merchantCategoryCode: "1171",
merchantName: "Tap Payments",
merchantCity: "Kuwait City",
postalCode: nil,
additionData: TapEmvcoAdditionalData(
billNumber: "Bill 123",
customerLabel: "Tap Customer",
loyaltyNumber: "123",
mobileNumber: "0096599999999",
purposeForTransaction: "Tap Transaction",
storeLabel: "Store 1",
terminalLabel: "Terminal 1",
additionalCustomerDataCollection: .addressPhone),
alternateLanguageData: TapEmvcoAlternateLanguage(
with: .ar,
alternatLanguageMerchantName: "تاب",
alternatLanguageMerchantCityName: "الكويت"))
}catch{
print(error.localizedDescription)
}
Objective-C:
@import TapQRCode_iOS;
NSError* error;
TapEmvcoPushData* tapEmvcoData = [[TapEmvcoPushData alloc]
initWithPointOfInitiation:TapEmvcoOfInitiationDynamic
merchantPaymentTags:@[[[TapEmvcoPaymentNetwork alloc]initWith:TapEmvcoNetworkTagsVisaTag02 value:@"4600678934521435"]]
transactionAmount:10
transactionCurrency:TapEmvcoCurrencyCodeKWD
extraFeesMode:TapEmvcoExtraFeesFixedFees
extraFeesAmount:5
countryCode:TapEmvcoCountryCodeKW
merchantCategoryCode:@"1171"
merchantName:@"Tap Payments"
merchantCity:@"Kuwait City"
postalCode:nil
additionData:[[TapEmvcoAdditionalData alloc]
initWithBillNumber:@"Bill 123"
customerLabel:@"Tap Customer"
loyaltyNumber:@"Loyal Number 1"
mobileNumber:@"+96599999999"
purposeForTransaction:@"Tap Transaction"
storeLabel:@"Tap Store # 1"
terminalLabel:@"Tap Terminal # 1"
additionalCustomerDataCollection:TapEmvcoAdditionalDataCollectionPhoneEmail]
alternateLanguageData:[[TapEmvcoAlternateLanguage alloc]
initWith:TapAlternateLanguageEnumAr
alternatLanguageMerchantName:@"تاب"
alternatLanguageMerchantCityName:@"الكويت"]
error:&error];
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
pointOfInitiation | TapEmvcoOfInitiation | 是 | 无 | 定义了二维码是静态的还是动态的。静态的可以多次支付,动态的只能支付一次。 为 EMVCO 点初始化方法(ID "01")提供描述性方式 |
merchantPaymentTags | [TapEmvcoPaymentNetwork] | 是 | 无 | 提供不同支付网络标签的商户全局标识列表。 至少提供一个支付标签 |
transactionAmount | Float | 否 | 0 | 交易金额,请注意,小数部分应与给定货币代码的官方小数部分匹配 |
transactionCurrency | TapEmvcoCurrencyCode | 是 | 无 | 交易的货币。 为 EMVCO 交易货币(ID "53")提供描述性方式 |
extraFeesMode | TapEmvcoExtraFees | 否 | .FixedFees | 定义额外的费用收集模式,是NONE、固定费用、总额的百分比,还是鼓励用户输入他想输入的任何费用。 为 EMVCO 小费或便利性指标(ID "55")提供描述性方式 |
extraFeesAmount | Float | 否 | 0 | 定义额外费用的值,如果为NONE或Prompt则无需传递,如果为固定费用,则是一个大于0的数值,如果为百分比则使用"00.01”和“99.99” |
countryCode | TapEmvcoCountryCode | 是 | 无 | 定义商户交易的所在国家的代码。为 EMVCO 国家代码(ID "58")提供描述性方式 |
merchantCategoryCode | String | 是 | 无 | 定义了商户的性质代码,如 ISO 18245 所定义。更多信息,请查阅 ISO 18245 |
merchantName | String | 是 | 无 | 定义商户的名字,最多25个字符 |
merchantCity | String | 是 | 无 | 定义商户的城市,最多25个字符 |
postalCode | String | 否 | 无 | 定义商户的邮政编码地址,最多25个字符 |
additionData | TapEmvcoAdditionalData | 否 | 无 | 定义了额外的数据字段模板(ID "62")。 详情见下文 |
alternateLanguageData | TapEmvcoAlternateLanguage | 否 | 无 | 定义语言模板(ID "64")。该模板显示商户名称和城市在其选择的本地化语言中。 |
TapEmvcoAdditionalData
此模型代表了一个更简单、更易于理解的包装器,用于在标准 EMVCO 数据中找到的 额外数据字段模板(ID "62")。我们希望在 Tap 上提供一个接口,使实体能够在不理解和阅读复杂的 EMVCO 标准的情况下生成 EMVCO 接受的代码。
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
billNumber | String | 否 | 无 | 发票号码或账单号码,总是截断到前25个字符。如果你想让手机应用程序收集它,请写为 *** |
customerLabel | String | 否 | 无 | 此值可以是商家提供的已知,或者可以作为对移动应用程序的提示,允许消费者输入他们的客户标签,总会被截断到前25个字符,如果您希望移动应用程序收集它,请将其写成 *** |
loyaltyNumber | String | 否 | 无 | 通常为忠诚度卡号,总会被截断到前25个字符,如果您希望移动应用程序收集它,请将其写成 *** |
mobileNumber | String | 否 | 无 | 用于多个用例的手机号码,例如移动充值和账单支付,总会被截断到前25个字符,如果您希望移动应用程序收集它,请将其写成 *** |
purposeForTransaction | String | 否 | 无 | 任何由商家或收单方定义的值,以定义交易目的,总会被截断到前25个字符,如果您希望移动应用程序收集它,请将其写成 *** |
storeLabel | String | 否 | 无 | 与某家商店关联的唯一标识符,总会被截断到前25个字符,如果您希望移动应用程序收集它,请将其写成 *** |
terminalLabel | String | 否 | 无 | 与商店内终端关联的唯一标识符,总会被截断到前25个字符,如果您希望移动应用程序收集它,请将其写成 *** |
additionalCustomerDataCollection | TapEmvcoAdditionalDataCollection | 否 | .None | 包含指示,让移动应用程序在完成交易时包含所需信息。所需信息应由移动应用程序在授权过程中提供,而不应不必要地提示消费者。如果存在,附加消费者数据请求(ID "09")应包含字符“A”、“M”和/或“E”的任何组合,并且每种字符只能有一个实例。 |
使用字典初始化TapEmvcoPushData
可以通过提供以下方式从JSON文件或后端响应中加载的字典来初始化TapEmvcoPushData:
Swift:
import TapQRCode_iOS
let url = Bundle.main.url(forResource: "EmvcoJson", withExtension: "json")!
let data = try! Data(contentsOf: url)
let emvcoDataFromJson:[String:Any] = try! JSONSerialization.jsonObject(with: data, options:.allowFragments) as! [String : Any]
do {
let tapEmvcoData:TapEmvcoPushData = try TapEmvcoPushData.init(withDictionary: emvcoDataFromJson)
}catch{
print(error.localizedDescription)
}
Objective-C:
@import TapQRCode_iOS;
NSError* error;
NSError* jsonError;
NSURL* url = [[NSBundle mainBundle] URLForResource:@"EmvcoJson" withExtension:@"json"];
NSData* data = [NSData dataWithContentsOfURL:url];
NSDictionary* emvcoDataFromJson = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&jsonError];
if(!jsonError)
{
TapEmvcoPushData* tapEmvcoData = [[TapEmvcoPushData alloc]initWithDictionary:emvcoDataFromJson error:&error];
NSLog(@"%@",@"");
}
接受的JSON格式
{
"pointOfInitiation": "12",
"merchantCategoryCode": "1711",
"merchantName": "Tap Payments",
"merchantCity": "Kuwait City",
"paymentNetworks": [
{
"tag": "VisaTag02",
"value": "4600678934521435"
},
{
"tag": "VisaTag03",
"value": "4600678934521467"
},
{
"tag": "MasterTag04",
"value": "555544443333111"
},
{
"tag": "MasterTag05",
"value": "555544443333222"
},
{
"tag": "NPCITag06",
"value": ""
},
{
"tag": "NPCITag07",
"value": ""
},
{
"tag": "AmexTag011",
"value": ""
},
{
"tag": "AmexTag012",
"value": ""
}
],
"countryCode": "KW",
"transactionCurrencyCode": "414",
"transactionAmount": 10,
"extraFeesMode": "02",
"extraFeesAmount": 5,
"billNumber": "123093133",
"customerLabel": "Tap Customer",
"terminalLabel": "POS 1",
"storeLabel": "Kuwait City",
"loyaltyNumber": "78876",
"mobileNumber": "0096599999999",
"purposeForTransaction": "Tap Transaction",
"additionalCustomerDataCollection": "ME",
"alternateLanguageLocale": "ar",
"alternateLanguageMerchantName":"تاب للمدفوعات",
"alternateLanguageMerchantCityName":"الكويت"
}
扫描QR码
以下是通过不同的方式扫描QR码的不同方法。
从静态图像中提取QR码
TapQRCodeScanner
可以扫描给定图像中的QR码,而不需要使用相机。
Swift:
import TapQRCode_iOS
let tapQRCodeScannerResult:TapQRCodeScannerResult = TapQRCodeScanner().scan(from: pickedImage)
Objective-C:
@import TapQRCode_iOS;
TapQRCodeScannerResult* tapQRCodeScannerResult = [[[TapQRCodeScanner alloc]init] scanFrom:pickedImage];
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
from | UIImage | 是 | 无 | 您想要从中提取QR码的UIImage |
内联QR码扫描器
TapQRCodeScanner
可以从指定的UIView的相机流中扫描QR码。因此,你可以将扫描器嵌入到你的布局中
Swift:
import TapQRCode_iOS
let tapBarCodeScanner:TapQRCodeScanner = TapQRCodeScanner()
tapBarCodeScanner.scan(inside: inlineView,
shouldHideUponScanning: true,
erroCallBack: { [weak self] error in
print (error)
},scannedCodeCallBack: { [weak self] tapScanResult in
print (tapScanResult.scannedText!)
},scannerRemovedCallBack: { [weak self] in
print("scannerStopped")
},introFadeIn: false,
outroFadeOut: false,
top:0, bottom:0, right:0, left:0)
Objective-C:
@import TapQRCode_iOS;
TapQRCodeScanner* tapQRCodeScanner = [[TapQRCodeScanner alloc]init];
[tapQRCodeScanner scanInside:inlineView
shouldHideUponScanning:YES
erroCallBack:^(NSString * error) {
NSLog(@"%@",error);
} scannedCodeCallBack:^(TapQRCodeScannerResult * scannerResult) {
NSLog(@"%@",scannerResult.scannedText);
} scannerRemovedCallBack:^{
NSLog(@"%@",@"Scanner removed");
} introFadeIn:NO outroFadeOut:NO
top:0 bottom:0 right:0 left:0];
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
持有视图 | UIView | 是 | 无 | 调用者希望显示扫描器的子视图 |
shouldHideUponScanning | 布尔值 | 否 | true | 如果为true,则扫描器在读取代码后会自动关闭。默认为true |
错误回调 | ((String) -> ()) | 否 | nil | 闭包用于发送任何错误字符串描述,该错误阻止了扫描器启动 |
扫描码回调 | ((TapQRCodeScannerResult) -> ()) | 否 | nil | 闭包用于发送扫描码的字符串描述 |
scannerRemovedCallBack | (() -> ()) | 否 | nil | 闭包用于通知扫描器被移除 |
introFadeIn | 布尔值 | 否 | false | 当设置为true时,扫描器准备就绪时会渐入 |
outroFadeOut | 布尔值 | 否 | false | 当设置为true时,扫描器在完成时会渐出 |
top | CGFloat | 否 | 0 | 从持有器的UIView的顶部边距。默认为0 |
bottom | CGFloat | 否 | 0 | 从持有器的UIView的底部边距。默认为0 |
right | CGFloat | 否 | 0 | 从持有器的UIView的右侧边距。默认为0 |
Left | CGFloat | 否 | 0 | 从持有器的UIView的左侧边距。默认为0 |
全屏模态QR码扫描器
TapQRCodeScanner
可以通过将扫描器作为模态从给定的UIViewController展示来在全屏模式下从相机流中扫描QR码
Swift:
import TapQRCode_iOS
TapQRCodeScanner().scan(fullScreen: self,
showTorchButton: true,
showOverlay: true,
showSwitchCameraButton: true,
statusBar: .default,
cancelButtonTitle: "Cancel",
torchButtonIcon: UIImage(named: "torchIcon"),
erroCallBack: { (error) in
print(error)
}, scannedCodeCallBack: { scannedValue in
print(scannedValue.scannedText ?? "")
}) {
print("Scanner Canceled")
}
参数:
参数名 | 参数类型 | 必需 | 默认值 | 描述 |
---|---|---|---|---|
fromController | UIViewController | 是 | 无 | 扫描器将被展示的视图控制器 |
showTorchButton | 布尔值 | 否 | true | 确定是否在扫描器上可见手电筒按钮。默认为true |
showOverlay | 布尔值 | 否 | true | 确定是否在扫描器上可见覆盖层。默认为true |
showSwitchCameraButton | 布尔值 | 否 | False | 确定是否在扫描器上可见切换按钮。默认为false |
statusBar | UIStatusBarStyle | 否 | .default | 确定所需的UIStatusBar样式。默认为.default |
cancelButtonTitle | String | 否 | 取消 | 确定取消按钮的标题。默认为取消 |
torchButtonIcon | UIImage | 否 | 无 | 如果你希望为手电筒按钮设置特定的图标 |
错误回调 | ((String) -> ()) | 否 | nil | 闭包用于发送任何错误字符串描述,该错误阻止了扫描器启动 |
扫描码回调 | ((TapQRCodeScannerResult) -> ()) | 否 | nil | 闭包用于发送扫描码的字符串描述 |
scannerCanceledCallBack | (() -> ()) | 否 | nil | 闭包用于在扫描器被取消时通知 |