Showing
12 changed files
with
379 additions
and
17 deletions
| @@ -26,6 +26,7 @@ | @@ -26,6 +26,7 @@ | ||
| 26 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; | 26 | 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; |
| 27 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; | 27 | 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; |
| 28 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; | 28 | 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; |
| 29 | + 5225F51353DA345E2811B6A4 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65E614A1DF8B88C7B0CE1B97 /* Pods_Runner.framework */; }; | ||
| 29 | /* End PBXBuildFile section */ | 30 | /* End PBXBuildFile section */ |
| 30 | 31 | ||
| 31 | /* Begin PBXContainerItemProxy section */ | 32 | /* Begin PBXContainerItemProxy section */ |
| @@ -54,7 +55,7 @@ | @@ -54,7 +55,7 @@ | ||
| 54 | /* Begin PBXFileReference section */ | 55 | /* Begin PBXFileReference section */ |
| 55 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; }; | 56 | 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; }; |
| 56 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; }; | 57 | 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; }; |
| 57 | - 33CC10ED2044A3C60003C045 /* mobile_scanner_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "mobile_scanner_example.app"; sourceTree = BUILT_PRODUCTS_DIR; }; | 58 | + 33CC10ED2044A3C60003C045 /* mobile_scanner_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = mobile_scanner_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; |
| 58 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; | 59 | 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; |
| 59 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; }; | 60 | 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; }; |
| 60 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; }; | 61 | 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; }; |
| @@ -66,8 +67,12 @@ | @@ -66,8 +67,12 @@ | ||
| 66 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; }; | 67 | 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; }; |
| 67 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; }; | 68 | 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; }; |
| 68 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; }; | 69 | 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; }; |
| 70 | + 65E614A1DF8B88C7B0CE1B97 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 69 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; | 71 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; }; |
| 70 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; | 72 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; }; |
| 73 | + CB0901144E09E7D7CA20584F /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; }; | ||
| 74 | + D522F9F6F348C5944077606B /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; | ||
| 75 | + F63009B5E287A1C82F9D7D2F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; | ||
| 71 | /* End PBXFileReference section */ | 76 | /* End PBXFileReference section */ |
| 72 | 77 | ||
| 73 | /* Begin PBXFrameworksBuildPhase section */ | 78 | /* Begin PBXFrameworksBuildPhase section */ |
| @@ -75,12 +80,23 @@ | @@ -75,12 +80,23 @@ | ||
| 75 | isa = PBXFrameworksBuildPhase; | 80 | isa = PBXFrameworksBuildPhase; |
| 76 | buildActionMask = 2147483647; | 81 | buildActionMask = 2147483647; |
| 77 | files = ( | 82 | files = ( |
| 83 | + 5225F51353DA345E2811B6A4 /* Pods_Runner.framework in Frameworks */, | ||
| 78 | ); | 84 | ); |
| 79 | runOnlyForDeploymentPostprocessing = 0; | 85 | runOnlyForDeploymentPostprocessing = 0; |
| 80 | }; | 86 | }; |
| 81 | /* End PBXFrameworksBuildPhase section */ | 87 | /* End PBXFrameworksBuildPhase section */ |
| 82 | 88 | ||
| 83 | /* Begin PBXGroup section */ | 89 | /* Begin PBXGroup section */ |
| 90 | + 20F8C9AA20C2A495C125E194 /* Pods */ = { | ||
| 91 | + isa = PBXGroup; | ||
| 92 | + children = ( | ||
| 93 | + CB0901144E09E7D7CA20584F /* Pods-Runner.debug.xcconfig */, | ||
| 94 | + D522F9F6F348C5944077606B /* Pods-Runner.release.xcconfig */, | ||
| 95 | + F63009B5E287A1C82F9D7D2F /* Pods-Runner.profile.xcconfig */, | ||
| 96 | + ); | ||
| 97 | + path = Pods; | ||
| 98 | + sourceTree = "<group>"; | ||
| 99 | + }; | ||
| 84 | 33BA886A226E78AF003329D5 /* Configs */ = { | 100 | 33BA886A226E78AF003329D5 /* Configs */ = { |
| 85 | isa = PBXGroup; | 101 | isa = PBXGroup; |
| 86 | children = ( | 102 | children = ( |
| @@ -98,7 +114,8 @@ | @@ -98,7 +114,8 @@ | ||
| 98 | 33FAB671232836740065AC1E /* Runner */, | 114 | 33FAB671232836740065AC1E /* Runner */, |
| 99 | 33CEB47122A05771004F2AC0 /* Flutter */, | 115 | 33CEB47122A05771004F2AC0 /* Flutter */, |
| 100 | 33CC10EE2044A3C60003C045 /* Products */, | 116 | 33CC10EE2044A3C60003C045 /* Products */, |
| 101 | - D73912EC22F37F3D000D13A0 /* Frameworks */, | 117 | + 20F8C9AA20C2A495C125E194 /* Pods */, |
| 118 | + 3539353E79638640B4999C09 /* Frameworks */, | ||
| 102 | ); | 119 | ); |
| 103 | sourceTree = "<group>"; | 120 | sourceTree = "<group>"; |
| 104 | }; | 121 | }; |
| @@ -145,9 +162,10 @@ | @@ -145,9 +162,10 @@ | ||
| 145 | path = Runner; | 162 | path = Runner; |
| 146 | sourceTree = "<group>"; | 163 | sourceTree = "<group>"; |
| 147 | }; | 164 | }; |
| 148 | - D73912EC22F37F3D000D13A0 /* Frameworks */ = { | 165 | + 3539353E79638640B4999C09 /* Frameworks */ = { |
| 149 | isa = PBXGroup; | 166 | isa = PBXGroup; |
| 150 | children = ( | 167 | children = ( |
| 168 | + 65E614A1DF8B88C7B0CE1B97 /* Pods_Runner.framework */, | ||
| 151 | ); | 169 | ); |
| 152 | name = Frameworks; | 170 | name = Frameworks; |
| 153 | sourceTree = "<group>"; | 171 | sourceTree = "<group>"; |
| @@ -159,11 +177,13 @@ | @@ -159,11 +177,13 @@ | ||
| 159 | isa = PBXNativeTarget; | 177 | isa = PBXNativeTarget; |
| 160 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; | 178 | buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; |
| 161 | buildPhases = ( | 179 | buildPhases = ( |
| 180 | + 696298230BDAD783AEC51C81 /* [CP] Check Pods Manifest.lock */, | ||
| 162 | 33CC10E92044A3C60003C045 /* Sources */, | 181 | 33CC10E92044A3C60003C045 /* Sources */, |
| 163 | 33CC10EA2044A3C60003C045 /* Frameworks */, | 182 | 33CC10EA2044A3C60003C045 /* Frameworks */, |
| 164 | 33CC10EB2044A3C60003C045 /* Resources */, | 183 | 33CC10EB2044A3C60003C045 /* Resources */, |
| 165 | 33CC110E2044A8840003C045 /* Bundle Framework */, | 184 | 33CC110E2044A8840003C045 /* Bundle Framework */, |
| 166 | 3399D490228B24CF009A79C7 /* ShellScript */, | 185 | 3399D490228B24CF009A79C7 /* ShellScript */, |
| 186 | + 8A90D2BC4083C5ACCEEBF32B /* [CP] Embed Pods Frameworks */, | ||
| 167 | ); | 187 | ); |
| 168 | buildRules = ( | 188 | buildRules = ( |
| 169 | ); | 189 | ); |
| @@ -270,6 +290,45 @@ | @@ -270,6 +290,45 @@ | ||
| 270 | shellPath = /bin/sh; | 290 | shellPath = /bin/sh; |
| 271 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; | 291 | shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; |
| 272 | }; | 292 | }; |
| 293 | + 696298230BDAD783AEC51C81 /* [CP] Check Pods Manifest.lock */ = { | ||
| 294 | + isa = PBXShellScriptBuildPhase; | ||
| 295 | + buildActionMask = 2147483647; | ||
| 296 | + files = ( | ||
| 297 | + ); | ||
| 298 | + inputFileListPaths = ( | ||
| 299 | + ); | ||
| 300 | + inputPaths = ( | ||
| 301 | + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", | ||
| 302 | + "${PODS_ROOT}/Manifest.lock", | ||
| 303 | + ); | ||
| 304 | + name = "[CP] Check Pods Manifest.lock"; | ||
| 305 | + outputFileListPaths = ( | ||
| 306 | + ); | ||
| 307 | + outputPaths = ( | ||
| 308 | + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", | ||
| 309 | + ); | ||
| 310 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 311 | + shellPath = /bin/sh; | ||
| 312 | + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | ||
| 313 | + showEnvVarsInLog = 0; | ||
| 314 | + }; | ||
| 315 | + 8A90D2BC4083C5ACCEEBF32B /* [CP] Embed Pods Frameworks */ = { | ||
| 316 | + isa = PBXShellScriptBuildPhase; | ||
| 317 | + buildActionMask = 2147483647; | ||
| 318 | + files = ( | ||
| 319 | + ); | ||
| 320 | + inputFileListPaths = ( | ||
| 321 | + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", | ||
| 322 | + ); | ||
| 323 | + name = "[CP] Embed Pods Frameworks"; | ||
| 324 | + outputFileListPaths = ( | ||
| 325 | + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", | ||
| 326 | + ); | ||
| 327 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 328 | + shellPath = /bin/sh; | ||
| 329 | + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; | ||
| 330 | + showEnvVarsInLog = 0; | ||
| 331 | + }; | ||
| 273 | /* End PBXShellScriptBuildPhase section */ | 332 | /* End PBXShellScriptBuildPhase section */ |
| 274 | 333 | ||
| 275 | /* Begin PBXSourcesBuildPhase section */ | 334 | /* Begin PBXSourcesBuildPhase section */ |
| @@ -344,7 +403,7 @@ | @@ -344,7 +403,7 @@ | ||
| 344 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
| 345 | GCC_WARN_UNUSED_FUNCTION = YES; | 404 | GCC_WARN_UNUSED_FUNCTION = YES; |
| 346 | GCC_WARN_UNUSED_VARIABLE = YES; | 405 | GCC_WARN_UNUSED_VARIABLE = YES; |
| 347 | - MACOSX_DEPLOYMENT_TARGET = 10.11; | 406 | + MACOSX_DEPLOYMENT_TARGET = 10.13; |
| 348 | MTL_ENABLE_DEBUG_INFO = NO; | 407 | MTL_ENABLE_DEBUG_INFO = NO; |
| 349 | SDKROOT = macosx; | 408 | SDKROOT = macosx; |
| 350 | SWIFT_COMPILATION_MODE = wholemodule; | 409 | SWIFT_COMPILATION_MODE = wholemodule; |
| @@ -366,6 +425,7 @@ | @@ -366,6 +425,7 @@ | ||
| 366 | "$(inherited)", | 425 | "$(inherited)", |
| 367 | "@executable_path/../Frameworks", | 426 | "@executable_path/../Frameworks", |
| 368 | ); | 427 | ); |
| 428 | + MACOSX_DEPLOYMENT_TARGET = 10.13; | ||
| 369 | PROVISIONING_PROFILE_SPECIFIER = ""; | 429 | PROVISIONING_PROFILE_SPECIFIER = ""; |
| 370 | SWIFT_VERSION = 5.0; | 430 | SWIFT_VERSION = 5.0; |
| 371 | }; | 431 | }; |
| @@ -423,7 +483,7 @@ | @@ -423,7 +483,7 @@ | ||
| 423 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 483 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
| 424 | GCC_WARN_UNUSED_FUNCTION = YES; | 484 | GCC_WARN_UNUSED_FUNCTION = YES; |
| 425 | GCC_WARN_UNUSED_VARIABLE = YES; | 485 | GCC_WARN_UNUSED_VARIABLE = YES; |
| 426 | - MACOSX_DEPLOYMENT_TARGET = 10.11; | 486 | + MACOSX_DEPLOYMENT_TARGET = 10.13; |
| 427 | MTL_ENABLE_DEBUG_INFO = YES; | 487 | MTL_ENABLE_DEBUG_INFO = YES; |
| 428 | ONLY_ACTIVE_ARCH = YES; | 488 | ONLY_ACTIVE_ARCH = YES; |
| 429 | SDKROOT = macosx; | 489 | SDKROOT = macosx; |
| @@ -470,7 +530,7 @@ | @@ -470,7 +530,7 @@ | ||
| 470 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | 530 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; |
| 471 | GCC_WARN_UNUSED_FUNCTION = YES; | 531 | GCC_WARN_UNUSED_FUNCTION = YES; |
| 472 | GCC_WARN_UNUSED_VARIABLE = YES; | 532 | GCC_WARN_UNUSED_VARIABLE = YES; |
| 473 | - MACOSX_DEPLOYMENT_TARGET = 10.11; | 533 | + MACOSX_DEPLOYMENT_TARGET = 10.13; |
| 474 | MTL_ENABLE_DEBUG_INFO = NO; | 534 | MTL_ENABLE_DEBUG_INFO = NO; |
| 475 | SDKROOT = macosx; | 535 | SDKROOT = macosx; |
| 476 | SWIFT_COMPILATION_MODE = wholemodule; | 536 | SWIFT_COMPILATION_MODE = wholemodule; |
| @@ -492,6 +552,7 @@ | @@ -492,6 +552,7 @@ | ||
| 492 | "$(inherited)", | 552 | "$(inherited)", |
| 493 | "@executable_path/../Frameworks", | 553 | "@executable_path/../Frameworks", |
| 494 | ); | 554 | ); |
| 555 | + MACOSX_DEPLOYMENT_TARGET = 10.13; | ||
| 495 | PROVISIONING_PROFILE_SPECIFIER = ""; | 556 | PROVISIONING_PROFILE_SPECIFIER = ""; |
| 496 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; | 557 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; |
| 497 | SWIFT_VERSION = 5.0; | 558 | SWIFT_VERSION = 5.0; |
| @@ -512,6 +573,7 @@ | @@ -512,6 +573,7 @@ | ||
| 512 | "$(inherited)", | 573 | "$(inherited)", |
| 513 | "@executable_path/../Frameworks", | 574 | "@executable_path/../Frameworks", |
| 514 | ); | 575 | ); |
| 576 | + MACOSX_DEPLOYMENT_TARGET = 10.13; | ||
| 515 | PROVISIONING_PROFILE_SPECIFIER = ""; | 577 | PROVISIONING_PROFILE_SPECIFIER = ""; |
| 516 | SWIFT_VERSION = 5.0; | 578 | SWIFT_VERSION = 5.0; |
| 517 | }; | 579 | }; |
| @@ -6,6 +6,8 @@ | @@ -6,6 +6,8 @@ | ||
| 6 | <true/> | 6 | <true/> |
| 7 | <key>com.apple.security.cs.allow-jit</key> | 7 | <key>com.apple.security.cs.allow-jit</key> |
| 8 | <true/> | 8 | <true/> |
| 9 | + <key>com.apple.security.device.camera</key> | ||
| 10 | + <true/> | ||
| 9 | <key>com.apple.security.network.server</key> | 11 | <key>com.apple.security.network.server</key> |
| 10 | <true/> | 12 | <true/> |
| 11 | </dict> | 13 | </dict> |
| @@ -2,6 +2,8 @@ | @@ -2,6 +2,8 @@ | ||
| 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | 2 | <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 3 | <plist version="1.0"> | 3 | <plist version="1.0"> |
| 4 | <dict> | 4 | <dict> |
| 5 | + <key>NSCameraUsageDescription</key> | ||
| 6 | + <string>The camera is required to scan barcodes or QR codes</string> | ||
| 5 | <key>CFBundleDevelopmentRegion</key> | 7 | <key>CFBundleDevelopmentRegion</key> |
| 6 | <string>$(DEVELOPMENT_LANGUAGE)</string> | 8 | <string>$(DEVELOPMENT_LANGUAGE)</string> |
| 7 | <key>CFBundleExecutable</key> | 9 | <key>CFBundleExecutable</key> |
| @@ -86,6 +86,9 @@ class MobileScannerController { | @@ -86,6 +86,9 @@ class MobileScannerController { | ||
| 86 | final barcode = Barcode.fromNative(data); | 86 | final barcode = Barcode.fromNative(data); |
| 87 | barcodesController.add(barcode); | 87 | barcodesController.add(barcode); |
| 88 | break; | 88 | break; |
| 89 | + case 'barcodeMac': | ||
| 90 | + barcodesController.add(Barcode(rawValue: data['payload'])); | ||
| 91 | + break; | ||
| 89 | default: | 92 | default: |
| 90 | throw UnimplementedError(); | 93 | throw UnimplementedError(); |
| 91 | } | 94 | } |
| @@ -18,7 +18,7 @@ class Barcode { | @@ -18,7 +18,7 @@ class Barcode { | ||
| 18 | /// Returns raw bytes as it was encoded in the barcode. | 18 | /// Returns raw bytes as it was encoded in the barcode. |
| 19 | /// | 19 | /// |
| 20 | /// Returns null if the raw bytes can not be determined. | 20 | /// Returns null if the raw bytes can not be determined. |
| 21 | - final Uint8List rawBytes; | 21 | + final Uint8List? rawBytes; |
| 22 | 22 | ||
| 23 | /// Returns barcode value as it was encoded in the barcode. Structured values are not parsed, for example: 'MEBKM:TITLE:Google;URL://www.google.com;;'. | 23 | /// Returns barcode value as it was encoded in the barcode. Structured values are not parsed, for example: 'MEBKM:TITLE:Google;URL://www.google.com;;'. |
| 24 | /// | 24 | /// |
| @@ -63,6 +63,8 @@ class Barcode { | @@ -63,6 +63,8 @@ class Barcode { | ||
| 63 | /// Gets parsed WiFi AP details. | 63 | /// Gets parsed WiFi AP details. |
| 64 | final WiFi? wifi; | 64 | final WiFi? wifi; |
| 65 | 65 | ||
| 66 | + Barcode({this.corners, this.format = BarcodeFormat.ean13, this.rawBytes, this.type = BarcodeType.text, this.calendarEvent, this.contactInfo, this.driverLicense, this.email, this.geoPoint, this.phone, this.sms, this.url, this.wifi, required this.rawValue}); | ||
| 67 | + | ||
| 66 | /// Create a [Barcode] from native data. | 68 | /// Create a [Barcode] from native data. |
| 67 | Barcode.fromNative(Map<dynamic, dynamic> data) | 69 | Barcode.fromNative(Map<dynamic, dynamic> data) |
| 68 | : corners = toCorners(data['corners']), | 70 | : corners = toCorners(data['corners']), |
| 1 | -import Cocoa | 1 | +import AVFoundation |
| 2 | import FlutterMacOS | 2 | import FlutterMacOS |
| 3 | +import Vision | ||
| 4 | + | ||
| 5 | +public class MobileScannerPlugin: NSObject, FlutterPlugin, FlutterStreamHandler, FlutterTexture, AVCaptureVideoDataOutputSampleBufferDelegate { | ||
| 6 | + | ||
| 7 | + let registry: FlutterTextureRegistry | ||
| 8 | + | ||
| 9 | + // Sink for publishing event changes | ||
| 10 | + var sink: FlutterEventSink! | ||
| 11 | + | ||
| 12 | + // Texture id of the camera preview | ||
| 13 | + var textureId: Int64! | ||
| 14 | + | ||
| 15 | + // Capture session of the camera | ||
| 16 | + var captureSession: AVCaptureSession! | ||
| 17 | + | ||
| 18 | + // The selected camera | ||
| 19 | + var device: AVCaptureDevice! | ||
| 20 | + | ||
| 21 | + // Image to be sent to the texture | ||
| 22 | + var latestBuffer: CVImageBuffer! | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + var analyzeMode: Int = 0 | ||
| 26 | + var analyzing: Bool = false | ||
| 27 | + var position = AVCaptureDevice.Position.back | ||
| 3 | 28 | ||
| 4 | -public class MobileScannerPlugin: NSObject, FlutterPlugin { | ||
| 5 | public static func register(with registrar: FlutterPluginRegistrar) { | 29 | public static func register(with registrar: FlutterPluginRegistrar) { |
| 6 | - let channel = FlutterMethodChannel(name: "mobile_scanner", binaryMessenger: registrar.messenger) | ||
| 7 | - let instance = MobileScannerPlugin() | ||
| 8 | - registrar.addMethodCallDelegate(instance, channel: channel) | 30 | + let instance = MobileScannerPlugin(registrar.textures) |
| 31 | + | ||
| 32 | + let method = FlutterMethodChannel(name: | ||
| 33 | + "dev.steenbakker.mobile_scanner/scanner/method", binaryMessenger: registrar.messenger) | ||
| 34 | + let event = FlutterEventChannel(name: | ||
| 35 | + "dev.steenbakker.mobile_scanner/scanner/event", binaryMessenger: registrar.messenger) | ||
| 36 | + registrar.addMethodCallDelegate(instance, channel: method) | ||
| 37 | + event.setStreamHandler(instance) | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + init(_ registry: FlutterTextureRegistry) { | ||
| 41 | + self.registry = registry | ||
| 42 | + super.init() | ||
| 9 | } | 43 | } |
| 10 | 44 | ||
| 45 | + | ||
| 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { | 46 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { |
| 12 | switch call.method { | 47 | switch call.method { |
| 13 | - case "getPlatformVersion": | ||
| 14 | - result("macOS " + ProcessInfo.processInfo.operatingSystemVersionString) | 48 | + case "state": |
| 49 | + checkPermission(call, result) | ||
| 50 | + case "request": | ||
| 51 | + requestPermission(call, result) | ||
| 52 | + case "start": | ||
| 53 | + start(call, result) | ||
| 54 | + case "torch": | ||
| 55 | + switchTorch(call, result) | ||
| 56 | + case "analyze": | ||
| 57 | + switchAnalyzeMode(call, result) | ||
| 58 | + case "stop": | ||
| 59 | + stop(result) | ||
| 15 | default: | 60 | default: |
| 16 | result(FlutterMethodNotImplemented) | 61 | result(FlutterMethodNotImplemented) |
| 17 | } | 62 | } |
| 18 | } | 63 | } |
| 64 | + | ||
| 65 | + // FlutterStreamHandler | ||
| 66 | + public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { | ||
| 67 | + sink = events | ||
| 68 | + return nil | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + // FlutterStreamHandler | ||
| 72 | + public func onCancel(withArguments arguments: Any?) -> FlutterError? { | ||
| 73 | + sink = nil | ||
| 74 | + return nil | ||
| 75 | + } | ||
| 76 | + | ||
| 77 | + // FlutterTexture | ||
| 78 | + public func copyPixelBuffer() -> Unmanaged<CVPixelBuffer>? { | ||
| 79 | + if latestBuffer == nil { | ||
| 80 | + return nil | ||
| 81 | + } | ||
| 82 | + return Unmanaged<CVPixelBuffer>.passRetained(latestBuffer) | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + var i = 0 | ||
| 86 | + | ||
| 87 | + | ||
| 88 | + // Gets called when a new image is added to the buffer | ||
| 89 | + public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) { | ||
| 90 | + i = i + 1; | ||
| 91 | + | ||
| 92 | + latestBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) | ||
| 93 | + registry.textureFrameAvailable(textureId) | ||
| 94 | + | ||
| 95 | + switch analyzeMode { | ||
| 96 | + case 1: // barcode | ||
| 97 | + | ||
| 98 | + // Limit the analyzer because the texture output will freeze otherwise | ||
| 99 | + if i / 10 == 1 { | ||
| 100 | + i = 0 | ||
| 101 | + } else { | ||
| 102 | + break | ||
| 103 | + } | ||
| 104 | + let imageRequestHandler = VNImageRequestHandler( | ||
| 105 | + cvPixelBuffer: latestBuffer, | ||
| 106 | + orientation: .right) | ||
| 107 | + | ||
| 108 | + do { | ||
| 109 | + try imageRequestHandler.perform([VNDetectBarcodesRequest { (request, error) in | ||
| 110 | + if error == nil { | ||
| 111 | + if let results = request.results as? [VNBarcodeObservation] { | ||
| 112 | + for barcode in results { | ||
| 113 | + let barcodeType = String(barcode.symbology.rawValue).replacingOccurrences(of: "VNBarcodeSymbology", with: "") | ||
| 114 | + let event: [String: Any?] = ["name": "barcodeMac", "data" : ["payload": barcode.payloadStringValue, "symbology": barcodeType]] | ||
| 115 | + self.sink?(event) | ||
| 116 | + | ||
| 117 | + // if barcodeType == "QR" { | ||
| 118 | + // let image = CIImage(image: source) | ||
| 119 | + // image?.cropping(to: barcode.boundingBox) | ||
| 120 | + // self.qrCodeDescriptor(qrCode: barcode, qrCodeImage: image!) | ||
| 121 | + // } | ||
| 122 | + } | ||
| 123 | + } | ||
| 124 | + } else { | ||
| 125 | + print(error!.localizedDescription) | ||
| 126 | + } | ||
| 127 | + }]) | ||
| 128 | + } catch { | ||
| 129 | + print(error) | ||
| 130 | + } | ||
| 131 | + | ||
| 132 | + default: // none | ||
| 133 | + break | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + func checkPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 138 | + if #available(macOS 10.14, *) { | ||
| 139 | + let status = AVCaptureDevice.authorizationStatus(for: .video) | ||
| 140 | + switch status { | ||
| 141 | + case .notDetermined: | ||
| 142 | + result(0) | ||
| 143 | + case .authorized: | ||
| 144 | + result(1) | ||
| 145 | + default: | ||
| 146 | + result(2) | ||
| 147 | + } | ||
| 148 | + } else { | ||
| 149 | + result(1) | ||
| 150 | + } | ||
| 151 | + } | ||
| 152 | + | ||
| 153 | + func requestPermission(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 154 | + if #available(macOS 10.14, *) { | ||
| 155 | + AVCaptureDevice.requestAccess(for: .video, completionHandler: { result($0) }) | ||
| 156 | + } else { | ||
| 157 | + result(0) | ||
| 158 | + } | ||
| 159 | + } | ||
| 160 | + | ||
| 161 | + func start(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 162 | + textureId = registry.register(self) | ||
| 163 | + captureSession = AVCaptureSession() | ||
| 164 | + | ||
| 165 | + let argReader = MapArgumentReader(call.arguments as? [String: Any]) | ||
| 166 | + | ||
| 167 | +// let ratio: Int = argReader.int(key: "ratio") | ||
| 168 | + let torch: Bool = argReader.bool(key: "torch") ?? false | ||
| 169 | + let facing: Int = argReader.int(key: "facing") ?? 1 | ||
| 170 | + | ||
| 171 | + // Set the camera to use | ||
| 172 | + position = facing == 0 ? AVCaptureDevice.Position.front : .back | ||
| 173 | + | ||
| 174 | + // Open the camera device | ||
| 175 | + if #available(macOS 10.15, *) { | ||
| 176 | + device = AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInWideAngleCamera], mediaType: .video, position: position).devices.first | ||
| 177 | + } else { | ||
| 178 | + device = AVCaptureDevice.devices(for: .video).filter({$0.position == position}).first | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + // Enable the torch if parameter is set and torch is available | ||
| 182 | + if (device.hasTorch) { | ||
| 183 | + do { | ||
| 184 | + try device.lockForConfiguration() | ||
| 185 | + device.torchMode = torch ? .on : .off | ||
| 186 | + device.unlockForConfiguration() | ||
| 187 | + } catch { | ||
| 188 | + result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + | ||
| 192 | + device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) | ||
| 193 | + captureSession.beginConfiguration() | ||
| 194 | + | ||
| 195 | + // Add device input | ||
| 196 | + do { | ||
| 197 | + let input = try AVCaptureDeviceInput(device: device) | ||
| 198 | + captureSession.addInput(input) | ||
| 199 | + } catch { | ||
| 200 | + result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) | ||
| 201 | + } | ||
| 202 | + captureSession.sessionPreset = AVCaptureSession.Preset.photo; | ||
| 203 | + // Add video output. | ||
| 204 | + let videoOutput = AVCaptureVideoDataOutput() | ||
| 205 | + | ||
| 206 | + videoOutput.videoSettings = [kCVPixelBufferPixelFormatTypeKey as String: kCVPixelFormatType_32BGRA] | ||
| 207 | + videoOutput.alwaysDiscardsLateVideoFrames = true | ||
| 208 | + | ||
| 209 | + videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main) | ||
| 210 | + captureSession.addOutput(videoOutput) | ||
| 211 | + for connection in videoOutput.connections { | ||
| 212 | +// connection.videoOrientation = .portrait | ||
| 213 | + if position == .front && connection.isVideoMirroringSupported { | ||
| 214 | + connection.isVideoMirrored = true | ||
| 215 | + } | ||
| 216 | + } | ||
| 217 | + captureSession.commitConfiguration() | ||
| 218 | + captureSession.startRunning() | ||
| 219 | + let dimensions = CMVideoFormatDescriptionGetDimensions(device.activeFormat.formatDescription) | ||
| 220 | + let size = ["width": Double(dimensions.width), "height": Double(dimensions.height)] | ||
| 221 | + let answer: [String : Any?] = ["textureId": textureId, "size": size, "torchable": device.hasTorch] | ||
| 222 | + result(answer) | ||
| 223 | + } | ||
| 224 | + | ||
| 225 | + func switchTorch(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 226 | + do { | ||
| 227 | + try device.lockForConfiguration() | ||
| 228 | + device.torchMode = call.arguments as! Int == 1 ? .on : .off | ||
| 229 | + device.unlockForConfiguration() | ||
| 230 | + result(nil) | ||
| 231 | + } catch { | ||
| 232 | + result(FlutterError(code: error.localizedDescription, message: nil, details: nil)) | ||
| 233 | + } | ||
| 234 | + } | ||
| 235 | + | ||
| 236 | + func switchAnalyzeMode(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) { | ||
| 237 | + analyzeMode = call.arguments as! Int | ||
| 238 | + result(nil) | ||
| 239 | + } | ||
| 240 | + | ||
| 241 | + func stop(_ result: FlutterResult) { | ||
| 242 | + captureSession.stopRunning() | ||
| 243 | + for input in captureSession.inputs { | ||
| 244 | + captureSession.removeInput(input) | ||
| 245 | + } | ||
| 246 | + for output in captureSession.outputs { | ||
| 247 | + captureSession.removeOutput(output) | ||
| 248 | + } | ||
| 249 | + device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) | ||
| 250 | + registry.unregisterTexture(textureId) | ||
| 251 | + | ||
| 252 | + analyzeMode = 0 | ||
| 253 | + latestBuffer = nil | ||
| 254 | + captureSession = nil | ||
| 255 | + device = nil | ||
| 256 | + textureId = nil | ||
| 257 | + | ||
| 258 | + result(nil) | ||
| 259 | + } | ||
| 260 | + | ||
| 261 | + // Observer for torch state | ||
| 262 | + public override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { | ||
| 263 | + switch keyPath { | ||
| 264 | + case "torchMode": | ||
| 265 | + // off = 0; on = 1; auto = 2; | ||
| 266 | + let state = change?[.newKey] as? Int | ||
| 267 | + let event: [String: Any?] = ["name": "torchState", "data": state] | ||
| 268 | + sink?(event) | ||
| 269 | + default: | ||
| 270 | + break | ||
| 271 | + } | ||
| 272 | + } | ||
| 273 | +} | ||
| 274 | + | ||
| 275 | +class MapArgumentReader { | ||
| 276 | + | ||
| 277 | + let args: [String: Any]? | ||
| 278 | + | ||
| 279 | + init(_ args: [String: Any]?) { | ||
| 280 | + self.args = args | ||
| 281 | + } | ||
| 282 | + | ||
| 283 | + func string(key: String) -> String? { | ||
| 284 | + return args?[key] as? String | ||
| 285 | + } | ||
| 286 | + | ||
| 287 | + func int(key: String) -> Int? { | ||
| 288 | + return (args?[key] as? NSNumber)?.intValue | ||
| 289 | + } | ||
| 290 | + | ||
| 291 | + func bool(key: String) -> Bool? { | ||
| 292 | + return (args?[key] as? NSNumber)?.boolValue | ||
| 293 | + } | ||
| 294 | + | ||
| 295 | + func stringArray(key: String) -> [String]? { | ||
| 296 | + return args?[key] as? [String] | ||
| 297 | + } | ||
| 298 | + | ||
| 19 | } | 299 | } |
macos/Classes/Util.swift
0 → 100644
| 1 | + |
| @@ -15,8 +15,7 @@ An universal scanner for Flutter based on MLKit. | @@ -15,8 +15,7 @@ An universal scanner for Flutter based on MLKit. | ||
| 15 | s.source = { :path => '.' } | 15 | s.source = { :path => '.' } |
| 16 | s.source_files = 'Classes/**/*' | 16 | s.source_files = 'Classes/**/*' |
| 17 | s.dependency 'FlutterMacOS' | 17 | s.dependency 'FlutterMacOS' |
| 18 | - | ||
| 19 | - s.platform = :osx, '10.11' | 18 | + s.platform = :osx, '10.13' |
| 20 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } | 19 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } |
| 21 | s.swift_version = '5.0' | 20 | s.swift_version = '5.0' |
| 22 | end | 21 | end |
| 1 | name: mobile_scanner | 1 | name: mobile_scanner |
| 2 | description: A universal scanner for Flutter based on MLKit. Uses CameraX on Android and AVFoundation on iOS. | 2 | description: A universal scanner for Flutter based on MLKit. Uses CameraX on Android and AVFoundation on iOS. |
| 3 | -version: 0.0.3 | 3 | +version: 0.1.0 |
| 4 | repository: https://github.com/juliansteenbakker/mobile_scanner | 4 | repository: https://github.com/juliansteenbakker/mobile_scanner |
| 5 | 5 | ||
| 6 | environment: | 6 | environment: |
| @@ -24,3 +24,5 @@ flutter: | @@ -24,3 +24,5 @@ flutter: | ||
| 24 | pluginClass: MobileScannerPlugin | 24 | pluginClass: MobileScannerPlugin |
| 25 | ios: | 25 | ios: |
| 26 | pluginClass: MobileScannerPlugin | 26 | pluginClass: MobileScannerPlugin |
| 27 | + macos: | ||
| 28 | + pluginClass: MobileScannerPlugin |
-
Please register or login to post a comment