app scaffold

This commit is contained in:
Guangfei.Zhao
2026-08-17 15:29:55 +08:00
commit 681688dfae
301 changed files with 18414 additions and 0 deletions
+38
View File
@@ -0,0 +1,38 @@
.idea/
.vagrant/
.sconsign.dblite
.svn/
.DS_Store
*.swp
profile
DerivedData/
build/
GeneratedPluginRegistrant.h
GeneratedPluginRegistrant.m
.generated/
*.pbxuser
*.mode1v3
*.mode2v3
*.perspectivev3
!default.pbxuser
!default.mode1v3
!default.mode2v3
!default.perspectivev3
xcuserdata
*.moved-aside
*.pyc
*sync/
Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh
@@ -0,0 +1,29 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint native_scan.podspec` to validate before publishing.
#
Pod::Spec.new do |s|
s.name = 'native_scan'
s.version = '0.0.1'
s.summary = 'A new Flutter plugin project.'
s.description = <<-DESC
A new Flutter plugin project.
DESC
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'native_scan/Sources/native_scan/**/*'
s.dependency 'Flutter'
s.platform = :ios, '13.0'
# Flutter.framework does not contain a i386 slice.
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' }
s.swift_version = '5.0'
# If your plugin requires a privacy manifest, for example if it uses any
# required reason APIs, update the PrivacyInfo.xcprivacy file to describe your
# plugin's privacy impact, and then uncomment this line. For more information,
# see https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
# s.resource_bundles = {'native_scan_privacy' => ['native_scan/Sources/native_scan/PrivacyInfo.xcprivacy']}
end
@@ -0,0 +1,36 @@
// swift-tools-version: 5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "native_scan",
platforms: [
.iOS("13.0")
],
products: [
.library(name: "native-scan", targets: ["native_scan"])
],
dependencies: [
.package(name: "FlutterFramework", path: "../FlutterFramework")
],
targets: [
.target(
name: "native_scan",
dependencies: [
.product(name: "FlutterFramework", package: "FlutterFramework")
],
resources: [
// If your plugin requires a privacy manifest, for example if it uses any required
// reason APIs, update the PrivacyInfo.xcprivacy file to describe your plugin's
// privacy impact, and then uncomment these lines. For more information, see
// https://developer.apple.com/documentation/bundleresources/privacy_manifest_files
// .process("PrivacyInfo.xcprivacy"),
// If you have other resources that need to be bundled with your plugin, refer to
// the following instructions to add them:
// https://developer.apple.com/documentation/xcode/bundling-resources-with-a-swift-package
]
)
]
)
@@ -0,0 +1,21 @@
import Flutter
import UIKit
/// iOS
///
/// TODO(native): conti-docs/07-native-integration.md
///
/// 1. pigeon `ScanHostApi` ScanApi.g.swift
/// 2. register `ScanHostApiSetup.setUp(binaryMessenger:api:)`
/// 3. Info.plist NSCameraUsageDescription
/// 4. / / FlutterErrorcode
/// CANCELLED / PERMISSION_DENIED / UNAVAILABLE Dart
/// NativeScanErrorCode ****
///
/// Dart MissingPluginException
/// NativeScan UNSUPPORTED_PLATFORM
public class NativeScanPlugin: NSObject, FlutterPlugin {
public static func register(with registrar: FlutterPluginRegistrar) {
// TODO(native): ScanHostApiSetup.setUp(binaryMessenger: registrar.messenger(), api: ScanApiImpl())
}
}
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTrackingDomains</key>
<array/>
<key>NSPrivacyAccessedAPITypes</key>
<array/>
<key>NSPrivacyCollectedDataTypes</key>
<array/>
<key>NSPrivacyTracking</key>
<false/>
</dict>
</plist>
@@ -0,0 +1,432 @@
// Autogenerated from Pigeon (v27.3.0), do not edit directly.
// See also: https://pub.dev/packages/pigeon
import Foundation
#if os(iOS)
import Flutter
#elseif os(macOS)
import FlutterMacOS
#else
#error("Unsupported platform.")
#endif
/// Error class for passing custom error details to Dart side.
final class PigeonError: Error {
let code: String
let message: String?
let details: Sendable?
init(code: String, message: String?, details: Sendable?) {
self.code = code
self.message = message
self.details = details
}
var localizedDescription: String {
return
"PigeonError(code: \(code), message: \(message ?? "<nil>"), details: \(details ?? "<nil>")"
}
}
private func wrapResult(_ result: Any?) -> [Any?] {
return [result]
}
private func wrapError(_ error: Any) -> [Any?] {
if let pigeonError = error as? PigeonError {
return [
pigeonError.code,
pigeonError.message,
pigeonError.details,
]
}
if let flutterError = error as? FlutterError {
return [
flutterError.code,
flutterError.message,
flutterError.details,
]
}
return [
"\(error)",
"\(Swift.type(of: error))",
"Stacktrace: \(Thread.callStackSymbols)",
]
}
enum ScanApiPigeonInternal {
static func isNullish(_ value: Any?) -> Bool {
guard let innerValue = value else {
return true
}
if case Optional<Any>.some(Optional<Any>.none) = value {
return true
}
return innerValue is NSNull
}
static func doubleEquals(_ lhs: Double, _ rhs: Double) -> Bool {
return (lhs.isNaN && rhs.isNaN) || lhs == rhs
}
static func doubleHash(_ value: Double, _ hasher: inout Hasher) {
if value.isNaN {
hasher.combine(0x7FF8000000000000)
} else {
// Normalize -0.0 to 0.0
hasher.combine(value == 0 ? 0 : value)
}
}
static func deepEquals(_ lhs: Any?, _ rhs: Any?) -> Bool {
let cleanLhs = nilOrValue(lhs) as Any?
let cleanRhs = nilOrValue(rhs) as Any?
switch (cleanLhs, cleanRhs) {
case (nil, nil):
return true
case (nil, _), (_, nil):
return false
case (let lhs as AnyObject, let rhs as AnyObject) where lhs === rhs:
return true
case is (Void, Void):
return true
case (let lhsArray, let rhsArray) as ([Any?], [Any?]):
guard lhsArray.count == rhsArray.count else { return false }
for (index, element) in lhsArray.enumerated() {
if !deepEquals(element, rhsArray[index]) {
return false
}
}
return true
case (let lhsArray, let rhsArray) as ([Double], [Double]):
guard lhsArray.count == rhsArray.count else { return false }
for (index, element) in lhsArray.enumerated() {
if !doubleEquals(element, rhsArray[index]) {
return false
}
}
return true
case (let lhsDictionary, let rhsDictionary) as ([AnyHashable: Any?], [AnyHashable: Any?]):
guard lhsDictionary.count == rhsDictionary.count else { return false }
for (lhsKey, lhsValue) in lhsDictionary {
var found = false
for (rhsKey, rhsValue) in rhsDictionary {
if deepEquals(lhsKey, rhsKey) {
if deepEquals(lhsValue, rhsValue) {
found = true
break
} else {
return false
}
}
}
if !found { return false }
}
return true
case (let lhs as Double, let rhs as Double):
return doubleEquals(lhs, rhs)
case (let lhsHashable, let rhsHashable) as (AnyHashable, AnyHashable):
return lhsHashable == rhsHashable
default:
return false
}
}
static func deepHash(value: Any?, hasher: inout Hasher) {
let cleanValue = nilOrValue(value) as Any?
if let cleanValue = cleanValue {
if let doubleValue = cleanValue as? Double {
doubleHash(doubleValue, &hasher)
} else if let valueList = cleanValue as? [Any?] {
for item in valueList {
deepHash(value: item, hasher: &hasher)
}
} else if let valueList = cleanValue as? [Double] {
for item in valueList {
doubleHash(item, &hasher)
}
} else if let valueDict = cleanValue as? [AnyHashable: Any?] {
var result = 0
for (key, value) in valueDict {
var entryKeyHasher = Hasher()
deepHash(value: key, hasher: &entryKeyHasher)
var entryValueHasher = Hasher()
deepHash(value: value, hasher: &entryValueHasher)
result = result &+ ((entryKeyHasher.finalize() &* 31) ^ entryValueHasher.finalize())
}
hasher.combine(result)
} else if let hashableValue = cleanValue as? AnyHashable {
hasher.combine(hashableValue)
} else {
hasher.combine(String(describing: cleanValue))
}
} else {
hasher.combine(0)
}
}
}
private func nilOrValue<T>(_ value: Any?) -> T? {
if value is NSNull { return nil }
return value as! T?
}
///
///
/// **使**07 §VIN
/// OCRVIN OCR +
/// schema
///
enum ScanMode: Int, CaseIterable {
/// /
case barcode = 0
/// VIN Code 39
case vin = 1
///
case plate = 2
}
///
///
/// Generated class from Pigeon that represents data sent in messages.
struct ScanOptions: Hashable, CustomStringConvertible {
///
var mode: ScanMode
/// null
var timeoutMs: Int64? = nil
///
var torchEnabled: Bool? = nil
/// `native_scan` i18n
var title: String? = nil
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> ScanOptions? {
let mode = pigeonVar_list[0] as! ScanMode
let timeoutMs: Int64? = nilOrValue(pigeonVar_list[1])
let torchEnabled: Bool? = nilOrValue(pigeonVar_list[2])
let title: String? = nilOrValue(pigeonVar_list[3])
return ScanOptions(
mode: mode,
timeoutMs: timeoutMs,
torchEnabled: torchEnabled,
title: title
)
}
func toList() -> [Any?] {
return [
mode,
timeoutMs,
torchEnabled,
title,
]
}
static func == (lhs: ScanOptions, rhs: ScanOptions) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return ScanApiPigeonInternal.deepEquals(lhs.mode, rhs.mode) && ScanApiPigeonInternal.deepEquals(lhs.timeoutMs, rhs.timeoutMs) && ScanApiPigeonInternal.deepEquals(lhs.torchEnabled, rhs.torchEnabled) && ScanApiPigeonInternal.deepEquals(lhs.title, rhs.title)
}
func hash(into hasher: inout Hasher) {
hasher.combine("ScanOptions")
ScanApiPigeonInternal.deepHash(value: mode, hasher: &hasher)
ScanApiPigeonInternal.deepHash(value: timeoutMs, hasher: &hasher)
ScanApiPigeonInternal.deepHash(value: torchEnabled, hasher: &hasher)
ScanApiPigeonInternal.deepHash(value: title, hasher: &hasher)
}
public var description: String {
return "ScanOptions(mode: \(String(describing: mode)), timeoutMs: \(String(describing: timeoutMs)), torchEnabled: \(String(describing: torchEnabled)), title: \(String(describing: title)))"
}
}
///
///
/// Generated class from Pigeon that represents data sent in messages.
struct ScanResult: Hashable, CustomStringConvertible {
///
var mode: ScanMode
///
var value: String
/// 13 `scan_succeeded`
var durationMs: Int64
/// `CODE_39` / `QR_CODE`OCR null
var rawFormat: String? = nil
// swift-format-ignore: AlwaysUseLowerCamelCase
static func fromList(_ pigeonVar_list: [Any?]) -> ScanResult? {
let mode = pigeonVar_list[0] as! ScanMode
let value = pigeonVar_list[1] as! String
let durationMs = pigeonVar_list[2] as! Int64
let rawFormat: String? = nilOrValue(pigeonVar_list[3])
return ScanResult(
mode: mode,
value: value,
durationMs: durationMs,
rawFormat: rawFormat
)
}
func toList() -> [Any?] {
return [
mode,
value,
durationMs,
rawFormat,
]
}
static func == (lhs: ScanResult, rhs: ScanResult) -> Bool {
if Swift.type(of: lhs) != Swift.type(of: rhs) {
return false
}
return ScanApiPigeonInternal.deepEquals(lhs.mode, rhs.mode) && ScanApiPigeonInternal.deepEquals(lhs.value, rhs.value) && ScanApiPigeonInternal.deepEquals(lhs.durationMs, rhs.durationMs) && ScanApiPigeonInternal.deepEquals(lhs.rawFormat, rhs.rawFormat)
}
func hash(into hasher: inout Hasher) {
hasher.combine("ScanResult")
ScanApiPigeonInternal.deepHash(value: mode, hasher: &hasher)
ScanApiPigeonInternal.deepHash(value: value, hasher: &hasher)
ScanApiPigeonInternal.deepHash(value: durationMs, hasher: &hasher)
ScanApiPigeonInternal.deepHash(value: rawFormat, hasher: &hasher)
}
public var description: String {
return "ScanResult(mode: \(String(describing: mode)), value: \(String(describing: value)), durationMs: \(String(describing: durationMs)), rawFormat: \(String(describing: rawFormat)))"
}
}
private class ScanApiPigeonCodecReader: FlutterStandardReader {
override func readValue(ofType type: UInt8) -> Any? {
switch type {
case 129:
let enumResultAsInt: Int? = nilOrValue(self.readValue() as! Int?)
if let enumResultAsInt = enumResultAsInt {
return ScanMode(rawValue: enumResultAsInt)
}
return nil
case 130:
return ScanOptions.fromList(self.readValue() as! [Any?])
case 131:
return ScanResult.fromList(self.readValue() as! [Any?])
default:
return super.readValue(ofType: type)
}
}
}
private class ScanApiPigeonCodecWriter: FlutterStandardWriter {
override func writeValue(_ value: Any) {
if let value = value as? ScanMode {
super.writeByte(129)
super.writeValue(value.rawValue)
} else if let value = value as? ScanOptions {
super.writeByte(130)
super.writeValue(value.toList())
} else if let value = value as? ScanResult {
super.writeByte(131)
super.writeValue(value.toList())
} else {
super.writeValue(value)
}
}
}
private class ScanApiPigeonCodecReaderWriter: FlutterStandardReaderWriter {
override func reader(with data: Data) -> FlutterStandardReader {
return ScanApiPigeonCodecReader(data: data)
}
override func writer(with data: NSMutableData) -> FlutterStandardWriter {
return ScanApiPigeonCodecWriter(data: data)
}
}
class ScanApiPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
static let shared = ScanApiPigeonCodec(readerWriter: ScanApiPigeonCodecReaderWriter())
}
/// Dart
///
/// `FlutterError`
/// Dart API `NativeScanException`**
/// `PlatformException`**07 §使
///
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
protocol ScanHostApi {
///
///
/// code `CANCELLED` null
///
func startScan(options: ScanOptions, completion: @escaping (Result<ScanResult, Error>) -> Void)
///
///
///
/// `startScan`
func isModeSupported(mode: ScanMode) throws -> Bool
}
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
class ScanHostApiSetup {
static var codec: FlutterStandardMessageCodec { ScanApiPigeonCodec.shared }
/// Sets up an instance of `ScanHostApi` to handle messages through the `binaryMessenger`.
static func setUp(binaryMessenger: FlutterBinaryMessenger, api: ScanHostApi?, messageChannelSuffix: String = "") {
let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : ""
///
///
/// code `CANCELLED` null
///
let startScanChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.native_scan.ScanHostApi.startScan\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
startScanChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let optionsArg = args[0] as! ScanOptions
api.startScan(options: optionsArg) { result in
switch result {
case .success(let res):
reply(wrapResult(res))
case .failure(let error):
reply(wrapError(error))
}
}
}
} else {
startScanChannel.setMessageHandler(nil)
}
///
///
///
/// `startScan`
let isModeSupportedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.native_scan.ScanHostApi.isModeSupported\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
isModeSupportedChannel.setMessageHandler { message, reply in
let args = message as! [Any?]
let modeArg = args[0] as! ScanMode
do {
let result = try api.isModeSupported(mode: modeArg)
reply(wrapResult(result))
} catch {
reply(wrapError(error))
}
}
} else {
isModeSupportedChannel.setMessageHandler(nil)
}
}
}