Implemented generating EPC QR code on iOS
This commit is contained in:
parent
0ed6c52ead
commit
e421cdb176
|
@ -3,10 +3,13 @@
|
||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 50;
|
objectVersion = 52;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
368A7CDD2560A48900252D96 /* LabelledTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 368A7CDC2560A48900252D96 /* LabelledTextField.swift */; };
|
||||||
|
368A7CEC2560A93500252D96 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 368A7CEE2560A93500252D96 /* Localizable.strings */; };
|
||||||
|
368A7CFA2560B2A000252D96 /* ZXingObjC in Frameworks */ = {isa = PBXBuildFile; productRef = 368A7CF92560B2A000252D96 /* ZXingObjC */; };
|
||||||
7555FF7F242A565900829871 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF7E242A565900829871 /* AppDelegate.swift */; };
|
7555FF7F242A565900829871 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF7E242A565900829871 /* AppDelegate.swift */; };
|
||||||
7555FF81242A565900829871 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF80242A565900829871 /* SceneDelegate.swift */; };
|
7555FF81242A565900829871 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF80242A565900829871 /* SceneDelegate.swift */; };
|
||||||
7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };
|
7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };
|
||||||
|
@ -51,6 +54,9 @@
|
||||||
/* End PBXCopyFilesBuildPhase section */
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
368A7CDC2560A48900252D96 /* LabelledTextField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelledTextField.swift; sourceTree = "<group>"; };
|
||||||
|
368A7CED2560A93500252D96 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
|
368A7CF12560A94C00252D96 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
7555FF7B242A565900829871 /* EpcQrCodeiOSApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EpcQrCodeiOSApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
7555FF7B242A565900829871 /* EpcQrCodeiOSApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EpcQrCodeiOSApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
7555FF7E242A565900829871 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
7555FF7E242A565900829871 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
7555FF80242A565900829871 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
7555FF80242A565900829871 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
@ -74,6 +80,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7555FFB2242A642300829871 /* EpcQrCode.framework in Frameworks */,
|
7555FFB2242A642300829871 /* EpcQrCode.framework in Frameworks */,
|
||||||
|
368A7CFA2560B2A000252D96 /* ZXingObjC in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -125,6 +132,8 @@
|
||||||
7555FF89242A565B00829871 /* LaunchScreen.storyboard */,
|
7555FF89242A565B00829871 /* LaunchScreen.storyboard */,
|
||||||
7555FF8C242A565B00829871 /* Info.plist */,
|
7555FF8C242A565B00829871 /* Info.plist */,
|
||||||
7555FF86242A565B00829871 /* Preview Content */,
|
7555FF86242A565B00829871 /* Preview Content */,
|
||||||
|
368A7CDC2560A48900252D96 /* LabelledTextField.swift */,
|
||||||
|
368A7CEE2560A93500252D96 /* Localizable.strings */,
|
||||||
);
|
);
|
||||||
path = EpcQrCodeiOSApp;
|
path = EpcQrCodeiOSApp;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -181,6 +190,9 @@
|
||||||
dependencies = (
|
dependencies = (
|
||||||
);
|
);
|
||||||
name = EpcQrCodeiOSApp;
|
name = EpcQrCodeiOSApp;
|
||||||
|
packageProductDependencies = (
|
||||||
|
368A7CF92560B2A000252D96 /* ZXingObjC */,
|
||||||
|
);
|
||||||
productName = EpcQrCodeiOSApp;
|
productName = EpcQrCodeiOSApp;
|
||||||
productReference = 7555FF7B242A565900829871 /* EpcQrCodeiOSApp.app */;
|
productReference = 7555FF7B242A565900829871 /* EpcQrCodeiOSApp.app */;
|
||||||
productType = "com.apple.product-type.application";
|
productType = "com.apple.product-type.application";
|
||||||
|
@ -251,8 +263,12 @@
|
||||||
knownRegions = (
|
knownRegions = (
|
||||||
en,
|
en,
|
||||||
Base,
|
Base,
|
||||||
|
de,
|
||||||
);
|
);
|
||||||
mainGroup = 7555FF72242A565900829871;
|
mainGroup = 7555FF72242A565900829871;
|
||||||
|
packageReferences = (
|
||||||
|
368A7CF82560B2A000252D96 /* XCRemoteSwiftPackageReference "zxingify-objc" */,
|
||||||
|
);
|
||||||
productRefGroup = 7555FF7C242A565900829871 /* Products */;
|
productRefGroup = 7555FF7C242A565900829871 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
|
@ -270,6 +286,7 @@
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7555FF8B242A565B00829871 /* LaunchScreen.storyboard in Resources */,
|
7555FF8B242A565B00829871 /* LaunchScreen.storyboard in Resources */,
|
||||||
|
368A7CEC2560A93500252D96 /* Localizable.strings in Resources */,
|
||||||
7555FF88242A565B00829871 /* Preview Assets.xcassets in Resources */,
|
7555FF88242A565B00829871 /* Preview Assets.xcassets in Resources */,
|
||||||
7555FF85242A565B00829871 /* Assets.xcassets in Resources */,
|
7555FF85242A565B00829871 /* Assets.xcassets in Resources */,
|
||||||
);
|
);
|
||||||
|
@ -316,6 +333,7 @@
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
368A7CDD2560A48900252D96 /* LabelledTextField.swift in Sources */,
|
||||||
7555FF7F242A565900829871 /* AppDelegate.swift in Sources */,
|
7555FF7F242A565900829871 /* AppDelegate.swift in Sources */,
|
||||||
7555FF81242A565900829871 /* SceneDelegate.swift in Sources */,
|
7555FF81242A565900829871 /* SceneDelegate.swift in Sources */,
|
||||||
7555FF83242A565900829871 /* ContentView.swift in Sources */,
|
7555FF83242A565900829871 /* ContentView.swift in Sources */,
|
||||||
|
@ -354,6 +372,15 @@
|
||||||
/* End PBXTargetDependency section */
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
|
368A7CEE2560A93500252D96 /* Localizable.strings */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
368A7CED2560A93500252D96 /* en */,
|
||||||
|
368A7CF12560A94C00252D96 /* de */,
|
||||||
|
);
|
||||||
|
name = Localizable.strings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7555FF89242A565B00829871 /* LaunchScreen.storyboard */ = {
|
7555FF89242A565B00829871 /* LaunchScreen.storyboard */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -369,6 +396,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
@ -429,6 +457,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_ANALYZER_NONNULL = YES;
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
|
||||||
|
@ -643,6 +672,25 @@
|
||||||
defaultConfigurationName = Release;
|
defaultConfigurationName = Release;
|
||||||
};
|
};
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
|
/* Begin XCRemoteSwiftPackageReference section */
|
||||||
|
368A7CF82560B2A000252D96 /* XCRemoteSwiftPackageReference "zxingify-objc" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/zxingify/zxingify-objc";
|
||||||
|
requirement = {
|
||||||
|
kind = upToNextMajorVersion;
|
||||||
|
minimumVersion = 3.6.7;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/* End XCRemoteSwiftPackageReference section */
|
||||||
|
|
||||||
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
368A7CF92560B2A000252D96 /* ZXingObjC */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 368A7CF82560B2A000252D96 /* XCRemoteSwiftPackageReference "zxingify-objc" */;
|
||||||
|
productName = ZXingObjC;
|
||||||
|
};
|
||||||
|
/* End XCSwiftPackageProductDependency section */
|
||||||
};
|
};
|
||||||
rootObject = 7555FF73242A565900829871 /* Project object */;
|
rootObject = 7555FF73242A565900829871 /* Project object */;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,119 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import EpcQrCode
|
import EpcQrCode
|
||||||
|
import ZXingObjC
|
||||||
|
|
||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
|
|
||||||
|
static private let ImageWidth: CGFloat = 350
|
||||||
|
|
||||||
|
static private let ImageHeight = Self.ImageWidth
|
||||||
|
|
||||||
|
|
||||||
|
@State private var receiver: String = ""
|
||||||
|
|
||||||
|
@State private var iban: String = ""
|
||||||
|
|
||||||
|
@State private var bic: String = ""
|
||||||
|
|
||||||
|
@State private var amount: String = ""
|
||||||
|
|
||||||
|
@State private var reference: String = ""
|
||||||
|
|
||||||
|
|
||||||
|
@State private var generatedQrCode: UIImage? = nil
|
||||||
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Text(MppTest().showMessage())
|
VStack {
|
||||||
|
Form {
|
||||||
|
Section {
|
||||||
|
LabelledTextField("Receiver", $receiver)
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
LabelledTextField("IBAN", $iban)
|
||||||
|
|
||||||
|
LabelledTextField("BIC", $bic)
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
HStack {
|
||||||
|
Text("Amount")
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
TextField("", text: $amount)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
.keyboardType(.numberPad)
|
||||||
|
}
|
||||||
|
|
||||||
|
VStack(alignment: .leading) {
|
||||||
|
Text("Reference")
|
||||||
|
|
||||||
|
TextField("", text: $reference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Section {
|
||||||
|
Button(action: self.generateQRCode) {
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text("Generate")
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let generatedQrCode = generatedQrCode {
|
||||||
|
Section {
|
||||||
|
VStack(alignment: .center) {
|
||||||
|
Image(uiImage: generatedQrCode)
|
||||||
|
.resizable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private func generateQRCode() {
|
||||||
|
let creator = EpcQrCodeCreator()
|
||||||
|
let param = CreatorParam(receiverName: receiver, iban: iban, bic: bic, amount: map(amount), reference: reference, noteToUser: nil, encoding: .utf8)
|
||||||
|
|
||||||
|
let qrCodeContent = creator.generateAsString(param: param)
|
||||||
|
|
||||||
|
self.generatedQrCode = generateQRCode(qrCodeContent)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func map(_ amount: String) -> KotlinDouble? {
|
||||||
|
if let double = Double(amount.replacingOccurrences(of: ",", with: ".")) {
|
||||||
|
return KotlinDouble(double: double)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private func generateQRCode(_ informationToEncode: String) -> UIImage? {
|
||||||
|
let writer = ZXQRCodeWriter()
|
||||||
|
|
||||||
|
let hints = ZXEncodeHints()
|
||||||
|
hints.errorCorrectionLevel = ZXQRCodeErrorCorrectionLevel.errorCorrectionLevelM()
|
||||||
|
|
||||||
|
if let result = try? writer.encode(informationToEncode, format: kBarcodeFormatQRCode, width: Int32(Self.ImageWidth), height: Int32(Self.ImageHeight), hints: hints) {
|
||||||
|
if let cgImage = ZXImage(matrix: result)?.cgimage {
|
||||||
|
return UIImage(cgImage: cgImage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct ContentView_Previews: PreviewProvider {
|
struct ContentView_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
ContentView()
|
ContentView()
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
|
||||||
|
struct LabelledTextField: View {
|
||||||
|
|
||||||
|
private let label: LocalizedStringKey
|
||||||
|
|
||||||
|
private var value: Binding<String>
|
||||||
|
|
||||||
|
private let placeholder: LocalizedStringKey
|
||||||
|
|
||||||
|
|
||||||
|
init(_ label: LocalizedStringKey, _ value: Binding<String>, _ placeholder: LocalizedStringKey = "") {
|
||||||
|
self.label = label
|
||||||
|
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
self.placeholder = placeholder
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text(label)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
TextField(placeholder, text: value)
|
||||||
|
.multilineTextAlignment(.trailing)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct LabelledTextField_Previews: PreviewProvider {
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
LabelledTextField("Label", .constant("Value"))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
"Receiver" = "Empfänger";
|
||||||
|
"IBAN" = "IBAN";
|
||||||
|
"BIC" = "BIC";
|
||||||
|
"Amount" = "Betrag";
|
||||||
|
"Reference" = "Verwendungszweck";
|
||||||
|
|
||||||
|
"Generate" = "Erzeugen";
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
"Receiver" = "Receiver";
|
||||||
|
"IBAN" = "IBAN";
|
||||||
|
"BIC" = "BIC";
|
||||||
|
"Amount" = "Amount";
|
||||||
|
"Reference" = "Reference";
|
||||||
|
|
||||||
|
"Generate" = "Generate";
|
Loading…
Reference in New Issue