├── example └── blue │ ├── assets │ ├── logo.png │ ├── logo216.png │ ├── logo222.png │ └── rabbit_black.jpg │ ├── ios │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner │ │ ├── AppDelegate.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── main.m │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile.lock │ └── Podfile │ ├── android │ ├── gradle.properties │ ├── .gitignore │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── example │ │ │ │ │ │ └── blue │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── settings.gradle │ └── build.gradle │ ├── .metadata │ ├── README.md │ ├── pubspec.yaml │ ├── .gitignore │ ├── test │ └── widget_test.dart │ └── lib │ └── main.dart ├── test └── esc_pos_bluetooth_test.dart ├── lib ├── esc_pos_bluetooth.dart └── src │ ├── enums.dart │ └── printer_bluetooth_manager.dart ├── .metadata ├── .vscode └── launch.json ├── pubspec.yaml ├── CHANGELOG.md ├── printers.md ├── LICENSE ├── .gitignore └── README.md /example/blue/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/assets/logo.png -------------------------------------------------------------------------------- /example/blue/assets/logo216.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/assets/logo216.png -------------------------------------------------------------------------------- /example/blue/assets/logo222.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/assets/logo222.png -------------------------------------------------------------------------------- /example/blue/assets/rabbit_black.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/assets/rabbit_black.jpg -------------------------------------------------------------------------------- /example/blue/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/blue/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/blue/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/blue/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wwandreww/esc_pos_bluetooth/HEAD/example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/blue/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /test/esc_pos_bluetooth_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | 3 | import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; 4 | 5 | void main() { 6 | test('Tests not implemented', () { 7 | expect(1, 1); 8 | }); 9 | } 10 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/blue/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /example/blue/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/blue/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/esc_pos_bluetooth.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * esc_pos_bluetooth 3 | * Created by Andrey Ushakov 4 | * 5 | * Copyright (c) 2020. All rights reserved. 6 | * See LICENSE for distribution and usage details. 7 | */ 8 | library esc_pos_bluetooth; 9 | 10 | export './src/enums.dart'; 11 | export './src/printer_bluetooth_manager.dart'; 12 | -------------------------------------------------------------------------------- /example/blue/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 0b8abb4724aa590dd0f429683339b1e045a1594d 8 | channel: stable 9 | 10 | project_type: package 11 | -------------------------------------------------------------------------------- /example/blue/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 27321ebbad34b0a3fafe99fac037102196d655ff 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/blue/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/blue/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Blue (example)", 9 | "request": "launch", 10 | "type": "dart", 11 | "program": "example/blue/lib/main.dart" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /example/blue/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/blue/android/app/src/main/kotlin/com/example/blue/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.blue 2 | 3 | import androidx.annotation.NonNull; 4 | import io.flutter.embedding.android.FlutterActivity 5 | import io.flutter.embedding.engine.FlutterEngine 6 | import io.flutter.plugins.GeneratedPluginRegistrant 7 | 8 | class MainActivity: FlutterActivity() { 9 | override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { 10 | GeneratedPluginRegistrant.registerWith(flutterEngine); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /example/blue/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: esc_pos_bluetooth 2 | description: The library allows to print receipts using an ESC/POS thermal Bluetooth printer. 3 | version: 0.4.1 4 | homepage: https://github.com/andrey-ushakov/esc_pos_bluetooth 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | 9 | dependencies: 10 | flutter: 11 | sdk: flutter 12 | rxdart: ^0.26.0 13 | esc_pos_utils: ^1.1.0 14 | # esc_pos_utils: 15 | # path: ../esc_pos_utils 16 | flutter_bluetooth_basic: ^0.1.7 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | 22 | flutter: 23 | -------------------------------------------------------------------------------- /example/blue/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /example/blue/README.md: -------------------------------------------------------------------------------- 1 | # blue 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/blue/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/blue/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/blue/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: blue 2 | description: A new Flutter project. 3 | version: 1.0.0+1 4 | 5 | environment: 6 | sdk: ">=2.12.0 <3.0.0" 7 | 8 | dependencies: 9 | flutter: 10 | sdk: flutter 11 | cupertino_icons: ^1.0.3 12 | oktoast: ^3.0.0 13 | image: ^3.0.2 14 | esc_pos_bluetooth: 15 | path: ../../ 16 | esc_pos_utils: ^1.1.0 17 | # esc_pos_utils: 18 | # path: ../../../esc_pos_utils 19 | charset_converter: ^2.0.0 20 | intl: ^0.17.0 21 | qr_flutter: ^4.0.0 22 | path_provider: ^2.0.2 23 | 24 | dev_dependencies: 25 | flutter_test: 26 | sdk: flutter 27 | 28 | flutter: 29 | uses-material-design: true 30 | assets: 31 | - assets/logo.png 32 | - assets/logo216.png 33 | - assets/logo222.png 34 | - assets/rabbit_black.jpg 35 | -------------------------------------------------------------------------------- /example/blue/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | -------------------------------------------------------------------------------- /example/blue/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [0.4.1] 2 | 3 | - Bump flutter_bluetooth_basic to ^0.1.7 4 | 5 | ## [0.4.0] 6 | 7 | - Bump esc_pos_utils to ^1.1.0. Using Generator instead of Ticket 8 | 9 | ## [0.3.0] 10 | 11 | - Null-Safety 12 | 13 | ## [0.2.8] 14 | 15 | - Bump esc_pos_utils 16 | 17 | ## [0.2.7] 18 | 19 | - Updated flutter_bluetooth_basic 20 | 21 | ## [0.2.6] 22 | 23 | - Updated flutter_bluetooth_basic 24 | 25 | ## [0.2.5] 26 | 27 | - Split data into chunks 28 | 29 | ## [0.2.4] 30 | 31 | - `startScan` timeout bug fixed. 32 | - Updated `esc_pos_utils` package version to `0.3.4`. 33 | 34 | ## [0.2.3] 35 | 36 | - Updated `esc_pos_utils` package version to `0.3.3`. 37 | 38 | ## [0.2.2] 39 | 40 | - Updated `esc_pos_utils` package version to `0.3.2`. 41 | 42 | ## [0.2.1] 43 | 44 | - Updated `esc_pos_utils` package version to `0.3.1` (Open Cash Drawer). 45 | 46 | ## [0.2.0] 47 | 48 | - Updated `esc_pos_utils` package version to `0.3.0` (Image and Barcode alignment). 49 | 50 | ## [0.1.1] 51 | 52 | - Updated `esc_pos_utils`, `flutter_bluetooth_basic` package versions 53 | 54 | ## [0.1.0] 55 | 56 | - Android and iOS Bluetooth printing support 57 | -------------------------------------------------------------------------------- /example/blue/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:blue/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /lib/src/enums.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * esc_pos_bluetooth 3 | * Created by Andrey Ushakov 4 | * 5 | * Copyright (c) 2020. All rights reserved. 6 | * See LICENSE for distribution and usage details. 7 | */ 8 | 9 | class PosPrintResult { 10 | const PosPrintResult._internal(this.value); 11 | final int value; 12 | static const success = PosPrintResult._internal(1); 13 | static const timeout = PosPrintResult._internal(2); 14 | static const printerNotSelected = PosPrintResult._internal(3); 15 | static const ticketEmpty = PosPrintResult._internal(4); 16 | static const printInProgress = PosPrintResult._internal(5); 17 | static const scanInProgress = PosPrintResult._internal(6); 18 | 19 | String get msg { 20 | if (value == PosPrintResult.success.value) { 21 | return 'Success'; 22 | } else if (value == PosPrintResult.timeout.value) { 23 | return 'Error. Printer connection timeout'; 24 | } else if (value == PosPrintResult.printerNotSelected.value) { 25 | return 'Error. Printer not selected'; 26 | } else if (value == PosPrintResult.ticketEmpty.value) { 27 | return 'Error. Ticket is empty'; 28 | } else if (value == PosPrintResult.printInProgress.value) { 29 | return 'Error. Another print in progress'; 30 | } else if (value == PosPrintResult.scanInProgress.value) { 31 | return 'Error. Printer scanning in progress'; 32 | } else { 33 | return 'Unknown error'; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /example/blue/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - charset_converter (0.0.1): 3 | - Flutter 4 | - Flutter (1.0.0) 5 | - flutter_bluetooth_basic (0.0.1): 6 | - Flutter 7 | - path_provider (0.0.1): 8 | - Flutter 9 | - path_provider_macos (0.0.1): 10 | - Flutter 11 | 12 | DEPENDENCIES: 13 | - charset_converter (from `.symlinks/plugins/charset_converter/ios`) 14 | - Flutter (from `Flutter`) 15 | - flutter_bluetooth_basic (from `.symlinks/plugins/flutter_bluetooth_basic/ios`) 16 | - path_provider (from `.symlinks/plugins/path_provider/ios`) 17 | - path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`) 18 | 19 | EXTERNAL SOURCES: 20 | charset_converter: 21 | :path: ".symlinks/plugins/charset_converter/ios" 22 | Flutter: 23 | :path: Flutter 24 | flutter_bluetooth_basic: 25 | :path: ".symlinks/plugins/flutter_bluetooth_basic/ios" 26 | path_provider: 27 | :path: ".symlinks/plugins/path_provider/ios" 28 | path_provider_macos: 29 | :path: ".symlinks/plugins/path_provider_macos/ios" 30 | 31 | SPEC CHECKSUMS: 32 | charset_converter: 215c7b04932ec2b9ba43be96a9bc34afed3e5322 33 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 34 | flutter_bluetooth_basic: 0e4e27e22b50b3a25cc1d1e131953feb4af414f4 35 | path_provider: fb74bd0465e96b594bb3b5088ee4a4e7bb1f2a9d 36 | path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 37 | 38 | PODFILE CHECKSUM: ae34db30f861e93537b77c454f870f0f18e8deef 39 | 40 | COCOAPODS: 1.8.4 41 | -------------------------------------------------------------------------------- /printers.md: -------------------------------------------------------------------------------- 1 | # Tested Printers 2 | Please add here printer models you have used with this library and any comments (works / something goes wrong). 3 | 4 | This will help to maintain and improve this library and to choose the right printer. 5 | 6 | Thank you for your contribution! 7 | 8 | ## Bluetooth Printers List 9 | | Model | Paper | Library Ver. | Comments | 10 | |---|---|---|---| 11 | | [MUNBYN IMP034-BK](https://images-na.ssl-images-amazon.com/images/I/514cEfTx%2BtL._SL1000_.jpg) | 58mm | 0.1.1 | No issues (Android, iOS) | 12 | | ER-80 | | 0.1.1 | [No issues](https://github.com/andrey-ushakov/esc_pos_bluetooth/issues/1#issuecomment-597723277) | 13 | | [Seiko RP-D10](https://www.sii.co.jp/sps/eg/product/unit/rpd_series.html) | | | [Printer not listed during scan](https://github.com/andrey-ushakov/esc_pos_printer/issues/48) | 14 | | [Bixolon SPP-L310](https://www.bixolon.com/product_view.php?idx=137) | | | [Printer not listed during scan](https://github.com/andrey-ushakov/esc_pos_printer/issues/85) | 15 | |POS-5802DD (Kkmoon)|58mm|0.2.2|`PosImageFn.bitImageRaster`: align left only ;
`PosImageFn.graphics`: doesn't work ;
`Ticket.image`: works ;
everything else works (Tested on iOS) | 16 | | MHT-P8001, MHT-P26, Jepod JP-81LYA ([#1](https://github.com/andrey-ushakov/esc_pos_bluetooth/issues/1#issuecomment-597723277)) |80mm|0.2.2|All 3 image printing methods doens't work ;
bold text: No ;
westEur code page: No (Tested on iOS) | 17 | | SmartPos Sp-300 BU |80mm|0.2.8|
  • Arabic not working
  • slow when printing image
  • unhandled exception when printing space
(Tested on Android) | 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Andrey Ushakov. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following 11 | disclaimer in the documentation and/or other materials provided 12 | with the distribution. 13 | * Neither the name of the copyright holder nor the names of its 14 | contributors may be used to endorse or promote products derived 15 | from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /example/blue/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 12 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 76 | pubspec.lock 77 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | blue 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | NSBluetoothAlwaysUsageDescription 43 | Bluetooth is used to scan for printers and send the data 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | NSBluetoothPeripheralUsageDescription 47 | Bluetooth is used to scan for printers and send the data 48 | UIBackgroundModes 49 | 50 | bluetooth-central 51 | bluetooth-peripheral 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /example/blue/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.example.blue" 42 | minSdkVersion 21 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 47 | } 48 | 49 | buildTypes { 50 | release { 51 | // TODO: Add your own signing config for the release build. 52 | // Signing with the debug keys for now, so `flutter run --release` works. 53 | signingConfig signingConfigs.debug 54 | } 55 | } 56 | } 57 | 58 | flutter { 59 | source '../..' 60 | } 61 | 62 | dependencies { 63 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 64 | testImplementation 'junit:junit:4.12' 65 | androidTestImplementation 'androidx.test:runner:1.1.1' 66 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' 67 | } 68 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/blue/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/blue/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esc_pos_bluetooth 2 | 3 | [![Pub Version](https://img.shields.io/pub/v/esc_pos_bluetooth)](https://pub.dev/packages/esc_pos_bluetooth) 4 | 5 | The library allows to print receipts using a Bluetooth printer. For WiFi/Ethernet printers, use [esc_pos_printer](https://github.com/andrey-ushakov/esc_pos_printer) library. 6 | 7 | 8 | ## TODO (PRs are welcomed!) 9 | * Split byte data into chunks: [issue](https://github.com/andrey-ushakov/esc_pos_bluetooth/issues/5) 10 | * Print QR Codes using the `GS ( k` command (printing QR code from an image already supported) 11 | * PDF-417 Barcodes using the `GS ( k` command 12 | * Line spacing using the `ESC 3 ` command 13 | 14 | ## How to Help 15 | * Test your printer and add it in the table: [Wifi/Network printer](https://github.com/andrey-ushakov/esc_pos_printer/blob/master/printers.md) or [Bluetooth printer](https://github.com/andrey-ushakov/esc_pos_bluetooth/blob/master/printers.md) 16 | * Test and report bugs 17 | * Share your ideas about what could be improved (code optimization, new features...) 18 | * PRs are welcomed! 19 | 20 | 21 | ## Tested Printers 22 | Here are some [printers tested with this library](printers.md). Please add the models you have tested to maintain and improve this library and help others to choose the right printer. 23 | 24 | 25 | ## Generate a Ticket 26 | 27 | ### Simple Ticket with Styles: 28 | ```dart 29 | Ticket testTicket() { 30 | final Ticket ticket = Ticket(PaperSize.mm80); 31 | 32 | ticket.text( 33 | 'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ'); 34 | ticket.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ', 35 | styles: PosStyles(codeTable: PosCodeTable.westEur)); 36 | ticket.text('Special 2: blåbærgrød', 37 | styles: PosStyles(codeTable: PosCodeTable.westEur)); 38 | 39 | ticket.text('Bold text', styles: PosStyles(bold: true)); 40 | ticket.text('Reverse text', styles: PosStyles(reverse: true)); 41 | ticket.text('Underlined text', 42 | styles: PosStyles(underline: true), linesAfter: 1); 43 | ticket.text('Align left', styles: PosStyles(align: PosAlign.left)); 44 | ticket.text('Align center', styles: PosStyles(align: PosAlign.center)); 45 | ticket.text('Align right', 46 | styles: PosStyles(align: PosAlign.right), linesAfter: 1); 47 | 48 | ticket.text('Text size 200%', 49 | styles: PosStyles( 50 | height: PosTextSize.size2, 51 | width: PosTextSize.size2, 52 | )); 53 | 54 | ticket.feed(2); 55 | ticket.cut(); 56 | return ticket; 57 | } 58 | ``` 59 | 60 | You can find more examples here: [esc_pos_utils](https://github.com/andrey-ushakov/esc_pos_utils). 61 | 62 | 63 | ## Print a Ticket 64 | 65 | ```dart 66 | PrinterBluetoothManager printerManager = PrinterBluetoothManager(); 67 | 68 | printerManager.scanResults.listen((printers) async { 69 | // store found printers 70 | }); 71 | printerManager.startScan(Duration(seconds: 4)); 72 | 73 | // ... 74 | 75 | printerManager.selectPrinter(printer); 76 | final PosPrintResult res = await printerManager.printTicket(testTicket()); 77 | 78 | print('Print result: ${res.msg}'); 79 | ``` 80 | 81 | For a complete example, check the demo project [example/blue](example/blue). 82 | 83 | 84 | ## Troubleshooting 85 | * If your printer prints only 5%-10% of an image and then stops, or it can't print more than 1 image on the same ticket, or it can't print long tickets, try to ajust `queueSleepTimeMs` of the `PrinterBluetoothManager.printTicket` (try 50 or 100ms): `printerManager.printTicket(await demoReceipt(paper), queueSleepTimeMs: 50);` 86 | 87 | 88 | ## Test Print 89 | test receipt 90 | 91 | test receipt 92 | -------------------------------------------------------------------------------- /example/blue/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def parse_KV_file(file, separator='=') 14 | file_abs_path = File.expand_path(file) 15 | if !File.exists? file_abs_path 16 | return []; 17 | end 18 | generated_key_values = {} 19 | skip_line_start_symbols = ["#", "/"] 20 | File.foreach(file_abs_path) do |line| 21 | next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } 22 | plugin = line.split(pattern=separator) 23 | if plugin.length == 2 24 | podname = plugin[0].strip() 25 | path = plugin[1].strip() 26 | podpath = File.expand_path("#{path}", file_abs_path) 27 | generated_key_values[podname] = podpath 28 | else 29 | puts "Invalid plugin specification: #{line}" 30 | end 31 | end 32 | generated_key_values 33 | end 34 | 35 | target 'Runner' do 36 | use_frameworks! 37 | use_modular_headers! 38 | 39 | # Flutter Pod 40 | 41 | copied_flutter_dir = File.join(__dir__, 'Flutter') 42 | copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') 43 | copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') 44 | unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) 45 | # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. 46 | # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. 47 | # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. 48 | 49 | generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') 50 | unless File.exist?(generated_xcode_build_settings_path) 51 | raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" 52 | end 53 | generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) 54 | cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; 55 | 56 | unless File.exist?(copied_framework_path) 57 | FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) 58 | end 59 | unless File.exist?(copied_podspec_path) 60 | FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) 61 | end 62 | end 63 | 64 | # Keep pod path relative so it can be checked into Podfile.lock. 65 | pod 'Flutter', :path => 'Flutter' 66 | 67 | # Plugin Pods 68 | 69 | # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock 70 | # referring to absolute paths on developers' machines. 71 | system('rm -rf .symlinks') 72 | system('mkdir -p .symlinks/plugins') 73 | plugin_pods = parse_KV_file('../.flutter-plugins') 74 | plugin_pods.each do |name, path| 75 | symlink = File.join('.symlinks', 'plugins', name) 76 | File.symlink(path, symlink) 77 | pod name, :path => File.join(symlink, 'ios') 78 | end 79 | end 80 | 81 | # Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. 82 | install! 'cocoapods', :disable_input_output_paths => true 83 | 84 | post_install do |installer| 85 | installer.pods_project.targets.each do |target| 86 | target.build_configurations.each do |config| 87 | config.build_settings['ENABLE_BITCODE'] = 'NO' 88 | config.build_settings['SWIFT_VERSION'] = '4.2' # <--- add this 89 | end 90 | end 91 | end 92 | -------------------------------------------------------------------------------- /lib/src/printer_bluetooth_manager.dart: -------------------------------------------------------------------------------- 1 | /* 2 | * esc_pos_bluetooth 3 | * Created by Andrey Ushakov 4 | * 5 | * Copyright (c) 2019-2020. All rights reserved. 6 | * See LICENSE for distribution and usage details. 7 | */ 8 | 9 | import 'dart:async'; 10 | import 'dart:io'; 11 | import 'package:esc_pos_utils/esc_pos_utils.dart'; 12 | import 'package:rxdart/rxdart.dart'; 13 | import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart'; 14 | import './enums.dart'; 15 | 16 | /// Bluetooth printer 17 | class PrinterBluetooth { 18 | PrinterBluetooth(this._device); 19 | final BluetoothDevice _device; 20 | 21 | String? get name => _device.name; 22 | String? get address => _device.address; 23 | int? get type => _device.type; 24 | } 25 | 26 | /// Printer Bluetooth Manager 27 | class PrinterBluetoothManager { 28 | final BluetoothManager _bluetoothManager = BluetoothManager.instance; 29 | bool _isPrinting = false; 30 | bool _isConnected = false; 31 | StreamSubscription? _scanResultsSubscription; 32 | StreamSubscription? _isScanningSubscription; 33 | PrinterBluetooth? _selectedPrinter; 34 | 35 | final BehaviorSubject _isScanning = BehaviorSubject.seeded(false); 36 | Stream get isScanningStream => _isScanning.stream; 37 | 38 | final BehaviorSubject> _scanResults = 39 | BehaviorSubject.seeded([]); 40 | Stream> get scanResults => _scanResults.stream; 41 | 42 | Future _runDelayed(int seconds) { 43 | return Future.delayed(Duration(seconds: seconds)); 44 | } 45 | 46 | void startScan(Duration timeout) async { 47 | _scanResults.add([]); 48 | 49 | _bluetoothManager.startScan(timeout: timeout); 50 | 51 | _scanResultsSubscription = _bluetoothManager.scanResults.listen((devices) { 52 | _scanResults.add(devices.map((d) => PrinterBluetooth(d)).toList()); 53 | }); 54 | 55 | _isScanningSubscription = 56 | _bluetoothManager.isScanning.listen((isScanningCurrent) async { 57 | // If isScanning value changed (scan just stopped) 58 | if (_isScanning.value! && !isScanningCurrent) { 59 | _scanResultsSubscription!.cancel(); 60 | _isScanningSubscription!.cancel(); 61 | } 62 | _isScanning.add(isScanningCurrent); 63 | }); 64 | } 65 | 66 | void stopScan() async { 67 | await _bluetoothManager.stopScan(); 68 | } 69 | 70 | void selectPrinter(PrinterBluetooth printer) { 71 | _selectedPrinter = printer; 72 | } 73 | 74 | Future writeBytes( 75 | List bytes, { 76 | int chunkSizeBytes = 20, 77 | int queueSleepTimeMs = 20, 78 | }) async { 79 | final Completer completer = Completer(); 80 | 81 | const int timeout = 5; 82 | if (_selectedPrinter == null) { 83 | return Future.value(PosPrintResult.printerNotSelected); 84 | } else if (_isScanning.value!) { 85 | return Future.value(PosPrintResult.scanInProgress); 86 | } else if (_isPrinting) { 87 | return Future.value(PosPrintResult.printInProgress); 88 | } 89 | 90 | _isPrinting = true; 91 | 92 | // We have to rescan before connecting, otherwise we can connect only once 93 | await _bluetoothManager.startScan(timeout: Duration(seconds: 1)); 94 | await _bluetoothManager.stopScan(); 95 | 96 | // Connect 97 | await _bluetoothManager.connect(_selectedPrinter!._device); 98 | 99 | // Subscribe to the events 100 | _bluetoothManager.state.listen((state) async { 101 | switch (state) { 102 | case BluetoothManager.CONNECTED: 103 | // To avoid double call 104 | if (!_isConnected) { 105 | final len = bytes.length; 106 | List> chunks = []; 107 | for (var i = 0; i < len; i += chunkSizeBytes) { 108 | var end = (i + chunkSizeBytes < len) ? i + chunkSizeBytes : len; 109 | chunks.add(bytes.sublist(i, end)); 110 | } 111 | 112 | for (var i = 0; i < chunks.length; i += 1) { 113 | await _bluetoothManager.writeData(chunks[i]); 114 | sleep(Duration(milliseconds: queueSleepTimeMs)); 115 | } 116 | 117 | completer.complete(PosPrintResult.success); 118 | } 119 | // TODO sending disconnect signal should be event-based 120 | _runDelayed(3).then((dynamic v) async { 121 | await _bluetoothManager.disconnect(); 122 | _isPrinting = false; 123 | }); 124 | _isConnected = true; 125 | break; 126 | case BluetoothManager.DISCONNECTED: 127 | _isConnected = false; 128 | break; 129 | default: 130 | break; 131 | } 132 | }); 133 | 134 | // Printing timeout 135 | _runDelayed(timeout).then((dynamic v) async { 136 | if (_isPrinting) { 137 | _isPrinting = false; 138 | completer.complete(PosPrintResult.timeout); 139 | } 140 | }); 141 | 142 | return completer.future; 143 | } 144 | 145 | Future printTicket( 146 | List bytes, { 147 | int chunkSizeBytes = 20, 148 | int queueSleepTimeMs = 20, 149 | }) async { 150 | if (bytes.isEmpty) { 151 | return Future.value(PosPrintResult.ticketEmpty); 152 | } 153 | return writeBytes( 154 | bytes, 155 | chunkSizeBytes: chunkSizeBytes, 156 | queueSleepTimeMs: queueSleepTimeMs, 157 | ); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /example/blue/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:typed_data'; 3 | import 'package:intl/intl.dart'; 4 | import 'package:qr_flutter/qr_flutter.dart'; 5 | import 'package:path_provider/path_provider.dart'; 6 | import 'package:flutter/services.dart'; 7 | import 'package:image/image.dart'; 8 | import 'package:esc_pos_utils/esc_pos_utils.dart'; 9 | import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; 10 | import 'package:flutter/material.dart' hide Image; 11 | import 'package:oktoast/oktoast.dart'; 12 | 13 | void main() => runApp(MyApp()); 14 | 15 | class MyApp extends StatelessWidget { 16 | @override 17 | Widget build(BuildContext context) { 18 | return OKToast( 19 | child: MaterialApp( 20 | title: 'Bluetooth demo', 21 | theme: ThemeData( 22 | primarySwatch: Colors.blue, 23 | ), 24 | home: MyHomePage(title: 'Bluetooth demo'), 25 | ), 26 | ); 27 | } 28 | } 29 | 30 | class MyHomePage extends StatefulWidget { 31 | MyHomePage({Key? key, required this.title}) : super(key: key); 32 | final String title; 33 | 34 | @override 35 | _MyHomePageState createState() => _MyHomePageState(); 36 | } 37 | 38 | class _MyHomePageState extends State { 39 | PrinterBluetoothManager printerManager = PrinterBluetoothManager(); 40 | List _devices = []; 41 | 42 | @override 43 | void initState() { 44 | super.initState(); 45 | 46 | printerManager.scanResults.listen((devices) async { 47 | // print('UI: Devices found ${devices.length}'); 48 | setState(() { 49 | _devices = devices; 50 | }); 51 | }); 52 | } 53 | 54 | void _startScanDevices() { 55 | setState(() { 56 | _devices = []; 57 | }); 58 | printerManager.startScan(Duration(seconds: 4)); 59 | } 60 | 61 | void _stopScanDevices() { 62 | printerManager.stopScan(); 63 | } 64 | 65 | Future> demoReceipt( 66 | PaperSize paper, CapabilityProfile profile) async { 67 | final Generator ticket = Generator(paper, profile); 68 | List bytes = []; 69 | 70 | // Print image 71 | // final ByteData data = await rootBundle.load('assets/rabbit_black.jpg'); 72 | // final Uint8List imageBytes = data.buffer.asUint8List(); 73 | // final Image? image = decodeImage(imageBytes); 74 | // bytes += ticket.image(image); 75 | 76 | bytes += ticket.text('GROCERYLY', 77 | styles: PosStyles( 78 | align: PosAlign.center, 79 | height: PosTextSize.size2, 80 | width: PosTextSize.size2, 81 | ), 82 | linesAfter: 1); 83 | 84 | bytes += ticket.text('889 Watson Lane', 85 | styles: PosStyles(align: PosAlign.center)); 86 | bytes += ticket.text('New Braunfels, TX', 87 | styles: PosStyles(align: PosAlign.center)); 88 | bytes += ticket.text('Tel: 830-221-1234', 89 | styles: PosStyles(align: PosAlign.center)); 90 | bytes += ticket.text('Web: www.example.com', 91 | styles: PosStyles(align: PosAlign.center), linesAfter: 1); 92 | 93 | bytes += ticket.hr(); 94 | bytes += ticket.row([ 95 | PosColumn(text: 'Qty', width: 1), 96 | PosColumn(text: 'Item', width: 7), 97 | PosColumn( 98 | text: 'Price', width: 2, styles: PosStyles(align: PosAlign.right)), 99 | PosColumn( 100 | text: 'Total', width: 2, styles: PosStyles(align: PosAlign.right)), 101 | ]); 102 | 103 | bytes += ticket.row([ 104 | PosColumn(text: '2', width: 1), 105 | PosColumn(text: 'ONION RINGS', width: 7), 106 | PosColumn( 107 | text: '0.99', width: 2, styles: PosStyles(align: PosAlign.right)), 108 | PosColumn( 109 | text: '1.98', width: 2, styles: PosStyles(align: PosAlign.right)), 110 | ]); 111 | bytes += ticket.row([ 112 | PosColumn(text: '1', width: 1), 113 | PosColumn(text: 'PIZZA', width: 7), 114 | PosColumn( 115 | text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)), 116 | PosColumn( 117 | text: '3.45', width: 2, styles: PosStyles(align: PosAlign.right)), 118 | ]); 119 | bytes += ticket.row([ 120 | PosColumn(text: '1', width: 1), 121 | PosColumn(text: 'SPRING ROLLS', width: 7), 122 | PosColumn( 123 | text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)), 124 | PosColumn( 125 | text: '2.99', width: 2, styles: PosStyles(align: PosAlign.right)), 126 | ]); 127 | bytes += ticket.row([ 128 | PosColumn(text: '3', width: 1), 129 | PosColumn(text: 'CRUNCHY STICKS', width: 7), 130 | PosColumn( 131 | text: '0.85', width: 2, styles: PosStyles(align: PosAlign.right)), 132 | PosColumn( 133 | text: '2.55', width: 2, styles: PosStyles(align: PosAlign.right)), 134 | ]); 135 | bytes += ticket.hr(); 136 | 137 | bytes += ticket.row([ 138 | PosColumn( 139 | text: 'TOTAL', 140 | width: 6, 141 | styles: PosStyles( 142 | height: PosTextSize.size2, 143 | width: PosTextSize.size2, 144 | )), 145 | PosColumn( 146 | text: '\$10.97', 147 | width: 6, 148 | styles: PosStyles( 149 | align: PosAlign.right, 150 | height: PosTextSize.size2, 151 | width: PosTextSize.size2, 152 | )), 153 | ]); 154 | 155 | bytes += ticket.hr(ch: '=', linesAfter: 1); 156 | 157 | bytes += ticket.row([ 158 | PosColumn( 159 | text: 'Cash', 160 | width: 7, 161 | styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), 162 | PosColumn( 163 | text: '\$15.00', 164 | width: 5, 165 | styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), 166 | ]); 167 | bytes += ticket.row([ 168 | PosColumn( 169 | text: 'Change', 170 | width: 7, 171 | styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), 172 | PosColumn( 173 | text: '\$4.03', 174 | width: 5, 175 | styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2)), 176 | ]); 177 | 178 | bytes += ticket.feed(2); 179 | bytes += ticket.text('Thank you!', 180 | styles: PosStyles(align: PosAlign.center, bold: true)); 181 | 182 | final now = DateTime.now(); 183 | final formatter = DateFormat('MM/dd/yyyy H:m'); 184 | final String timestamp = formatter.format(now); 185 | bytes += ticket.text(timestamp, 186 | styles: PosStyles(align: PosAlign.center), linesAfter: 2); 187 | 188 | // Print QR Code from image 189 | // try { 190 | // const String qrData = 'example.com'; 191 | // const double qrSize = 200; 192 | // final uiImg = await QrPainter( 193 | // data: qrData, 194 | // version: QrVersions.auto, 195 | // gapless: false, 196 | // ).toImageData(qrSize); 197 | // final dir = await getTemporaryDirectory(); 198 | // final pathName = '${dir.path}/qr_tmp.png'; 199 | // final qrFile = File(pathName); 200 | // final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List()); 201 | // final img = decodeImage(imgFile.readAsBytesSync()); 202 | 203 | // bytes += ticket.image(img); 204 | // } catch (e) { 205 | // print(e); 206 | // } 207 | 208 | // Print QR Code using native function 209 | // bytes += ticket.qrcode('example.com'); 210 | 211 | ticket.feed(2); 212 | ticket.cut(); 213 | return bytes; 214 | } 215 | 216 | Future> testTicket( 217 | PaperSize paper, CapabilityProfile profile) async { 218 | final Generator generator = Generator(paper, profile); 219 | List bytes = []; 220 | 221 | bytes += generator.text( 222 | 'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ'); 223 | // bytes += generator.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ', 224 | // styles: PosStyles(codeTable: PosCodeTable.westEur)); 225 | // bytes += generator.text('Special 2: blåbærgrød', 226 | // styles: PosStyles(codeTable: PosCodeTable.westEur)); 227 | 228 | bytes += generator.text('Bold text', styles: PosStyles(bold: true)); 229 | bytes += generator.text('Reverse text', styles: PosStyles(reverse: true)); 230 | bytes += generator.text('Underlined text', 231 | styles: PosStyles(underline: true), linesAfter: 1); 232 | bytes += 233 | generator.text('Align left', styles: PosStyles(align: PosAlign.left)); 234 | bytes += generator.text('Align center', 235 | styles: PosStyles(align: PosAlign.center)); 236 | bytes += generator.text('Align right', 237 | styles: PosStyles(align: PosAlign.right), linesAfter: 1); 238 | 239 | bytes += generator.row([ 240 | PosColumn( 241 | text: 'col3', 242 | width: 3, 243 | styles: PosStyles(align: PosAlign.center, underline: true), 244 | ), 245 | PosColumn( 246 | text: 'col6', 247 | width: 6, 248 | styles: PosStyles(align: PosAlign.center, underline: true), 249 | ), 250 | PosColumn( 251 | text: 'col3', 252 | width: 3, 253 | styles: PosStyles(align: PosAlign.center, underline: true), 254 | ), 255 | ]); 256 | 257 | bytes += generator.text('Text size 200%', 258 | styles: PosStyles( 259 | height: PosTextSize.size2, 260 | width: PosTextSize.size2, 261 | )); 262 | 263 | // Print image 264 | final ByteData data = await rootBundle.load('assets/logo.png'); 265 | final Uint8List buf = data.buffer.asUint8List(); 266 | final Image image = decodeImage(buf)!; 267 | bytes += generator.image(image); 268 | // Print image using alternative commands 269 | // bytes += generator.imageRaster(image); 270 | // bytes += generator.imageRaster(image, imageFn: PosImageFn.graphics); 271 | 272 | // Print barcode 273 | final List barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4]; 274 | bytes += generator.barcode(Barcode.upcA(barData)); 275 | 276 | // Print mixed (chinese + latin) text. Only for printers supporting Kanji mode 277 | // bytes += generator.text( 278 | // 'hello ! 中文字 # world @ éphémère &', 279 | // styles: PosStyles(codeTable: PosCodeTable.westEur), 280 | // containsChinese: true, 281 | // ); 282 | 283 | bytes += generator.feed(2); 284 | 285 | bytes += generator.cut(); 286 | return bytes; 287 | } 288 | 289 | void _testPrint(PrinterBluetooth printer) async { 290 | printerManager.selectPrinter(printer); 291 | 292 | // TODO Don't forget to choose printer's paper 293 | const PaperSize paper = PaperSize.mm80; 294 | final profile = await CapabilityProfile.load(); 295 | 296 | // TEST PRINT 297 | // final PosPrintResult res = 298 | // await printerManager.printTicket(await testTicket(paper)); 299 | 300 | // DEMO RECEIPT 301 | final PosPrintResult res = 302 | await printerManager.printTicket((await demoReceipt(paper, profile))); 303 | 304 | showToast(res.msg); 305 | } 306 | 307 | @override 308 | Widget build(BuildContext context) { 309 | return Scaffold( 310 | appBar: AppBar( 311 | title: Text(widget.title), 312 | ), 313 | body: ListView.builder( 314 | itemCount: _devices.length, 315 | itemBuilder: (BuildContext context, int index) { 316 | return InkWell( 317 | onTap: () => _testPrint(_devices[index]), 318 | child: Column( 319 | children: [ 320 | Container( 321 | height: 60, 322 | padding: EdgeInsets.only(left: 10), 323 | alignment: Alignment.centerLeft, 324 | child: Row( 325 | children: [ 326 | Icon(Icons.print), 327 | SizedBox(width: 10), 328 | Expanded( 329 | child: Column( 330 | crossAxisAlignment: CrossAxisAlignment.start, 331 | mainAxisAlignment: MainAxisAlignment.center, 332 | children: [ 333 | Text(_devices[index].name ?? ''), 334 | Text(_devices[index].address!), 335 | Text( 336 | 'Click to print a test receipt', 337 | style: TextStyle(color: Colors.grey[700]), 338 | ), 339 | ], 340 | ), 341 | ) 342 | ], 343 | ), 344 | ), 345 | Divider(), 346 | ], 347 | ), 348 | ); 349 | }), 350 | floatingActionButton: StreamBuilder( 351 | stream: printerManager.isScanningStream, 352 | initialData: false, 353 | builder: (c, snapshot) { 354 | if (snapshot.data!) { 355 | return FloatingActionButton( 356 | child: Icon(Icons.stop), 357 | onPressed: _stopScanDevices, 358 | backgroundColor: Colors.red, 359 | ); 360 | } else { 361 | return FloatingActionButton( 362 | child: Icon(Icons.search), 363 | onPressed: _startScanDevices, 364 | ); 365 | } 366 | }, 367 | ), 368 | ); 369 | } 370 | } 371 | -------------------------------------------------------------------------------- /example/blue/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 13 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | 9BF580C952D09CCF033A2F91 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A617744456BDAEBB0A61C4 /* Pods_Runner.framework */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 36 | 28A617744456BDAEBB0A61C4 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 37 | 31A8528493424BB47F417B49 /* 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 = ""; }; 38 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 39 | 4DBC88598EB83611427B342E /* 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 = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 44 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 45 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 47 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 48 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 49 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 50 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 51 | E1B87060C53FEC09BE1B0C7C /* 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 = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | 9BF580C952D09CCF033A2F91 /* Pods_Runner.framework in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 877A50BEF1C0FB284671560C /* Pods */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 31A8528493424BB47F417B49 /* Pods-Runner.debug.xcconfig */, 70 | 4DBC88598EB83611427B342E /* Pods-Runner.release.xcconfig */, 71 | E1B87060C53FEC09BE1B0C7C /* Pods-Runner.profile.xcconfig */, 72 | ); 73 | path = Pods; 74 | sourceTree = ""; 75 | }; 76 | 9740EEB11CF90186004384FC /* Flutter */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 83 | ); 84 | name = Flutter; 85 | sourceTree = ""; 86 | }; 87 | 97C146E51CF9000F007C117D = { 88 | isa = PBXGroup; 89 | children = ( 90 | 9740EEB11CF90186004384FC /* Flutter */, 91 | 97C146F01CF9000F007C117D /* Runner */, 92 | 97C146EF1CF9000F007C117D /* Products */, 93 | 877A50BEF1C0FB284671560C /* Pods */, 94 | A12430A4DEE0E50A7AF77B73 /* Frameworks */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | 97C146EF1CF9000F007C117D /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 97C146EE1CF9000F007C117D /* Runner.app */, 102 | ); 103 | name = Products; 104 | sourceTree = ""; 105 | }; 106 | 97C146F01CF9000F007C117D /* Runner */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 110 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 111 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 112 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 113 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 114 | 97C147021CF9000F007C117D /* Info.plist */, 115 | 97C146F11CF9000F007C117D /* Supporting Files */, 116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 118 | ); 119 | path = Runner; 120 | sourceTree = ""; 121 | }; 122 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 97C146F21CF9000F007C117D /* main.m */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | A12430A4DEE0E50A7AF77B73 /* Frameworks */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 28A617744456BDAEBB0A61C4 /* Pods_Runner.framework */, 134 | ); 135 | name = Frameworks; 136 | sourceTree = ""; 137 | }; 138 | /* End PBXGroup section */ 139 | 140 | /* Begin PBXNativeTarget section */ 141 | 97C146ED1CF9000F007C117D /* Runner */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 144 | buildPhases = ( 145 | 10D669D5285F24E58D74D4E8 /* [CP] Check Pods Manifest.lock */, 146 | 9740EEB61CF901F6004384FC /* Run Script */, 147 | 97C146EA1CF9000F007C117D /* Sources */, 148 | 97C146EB1CF9000F007C117D /* Frameworks */, 149 | 97C146EC1CF9000F007C117D /* Resources */, 150 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 151 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 152 | DE9090B956159A2A305EA0E1 /* [CP] Embed Pods Frameworks */, 153 | ); 154 | buildRules = ( 155 | ); 156 | dependencies = ( 157 | ); 158 | name = Runner; 159 | productName = Runner; 160 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 161 | productType = "com.apple.product-type.application"; 162 | }; 163 | /* End PBXNativeTarget section */ 164 | 165 | /* Begin PBXProject section */ 166 | 97C146E61CF9000F007C117D /* Project object */ = { 167 | isa = PBXProject; 168 | attributes = { 169 | LastUpgradeCheck = 1020; 170 | ORGANIZATIONNAME = "The Chromium Authors"; 171 | TargetAttributes = { 172 | 97C146ED1CF9000F007C117D = { 173 | CreatedOnToolsVersion = 7.3.1; 174 | DevelopmentTeam = 8YA3WTV6AF; 175 | }; 176 | }; 177 | }; 178 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 179 | compatibilityVersion = "Xcode 3.2"; 180 | developmentRegion = en; 181 | hasScannedForEncodings = 0; 182 | knownRegions = ( 183 | en, 184 | Base, 185 | ); 186 | mainGroup = 97C146E51CF9000F007C117D; 187 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 188 | projectDirPath = ""; 189 | projectRoot = ""; 190 | targets = ( 191 | 97C146ED1CF9000F007C117D /* Runner */, 192 | ); 193 | }; 194 | /* End PBXProject section */ 195 | 196 | /* Begin PBXResourcesBuildPhase section */ 197 | 97C146EC1CF9000F007C117D /* Resources */ = { 198 | isa = PBXResourcesBuildPhase; 199 | buildActionMask = 2147483647; 200 | files = ( 201 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 202 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 203 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 204 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 205 | ); 206 | runOnlyForDeploymentPostprocessing = 0; 207 | }; 208 | /* End PBXResourcesBuildPhase section */ 209 | 210 | /* Begin PBXShellScriptBuildPhase section */ 211 | 10D669D5285F24E58D74D4E8 /* [CP] Check Pods Manifest.lock */ = { 212 | isa = PBXShellScriptBuildPhase; 213 | buildActionMask = 2147483647; 214 | files = ( 215 | ); 216 | inputFileListPaths = ( 217 | ); 218 | inputPaths = ( 219 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 220 | "${PODS_ROOT}/Manifest.lock", 221 | ); 222 | name = "[CP] Check Pods Manifest.lock"; 223 | outputFileListPaths = ( 224 | ); 225 | outputPaths = ( 226 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | shellPath = /bin/sh; 230 | 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"; 231 | showEnvVarsInLog = 0; 232 | }; 233 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 234 | isa = PBXShellScriptBuildPhase; 235 | buildActionMask = 2147483647; 236 | files = ( 237 | ); 238 | inputPaths = ( 239 | ); 240 | name = "Thin Binary"; 241 | outputPaths = ( 242 | ); 243 | runOnlyForDeploymentPostprocessing = 0; 244 | shellPath = /bin/sh; 245 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 246 | }; 247 | 9740EEB61CF901F6004384FC /* Run Script */ = { 248 | isa = PBXShellScriptBuildPhase; 249 | buildActionMask = 2147483647; 250 | files = ( 251 | ); 252 | inputPaths = ( 253 | ); 254 | name = "Run Script"; 255 | outputPaths = ( 256 | ); 257 | runOnlyForDeploymentPostprocessing = 0; 258 | shellPath = /bin/sh; 259 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 260 | }; 261 | DE9090B956159A2A305EA0E1 /* [CP] Embed Pods Frameworks */ = { 262 | isa = PBXShellScriptBuildPhase; 263 | buildActionMask = 2147483647; 264 | files = ( 265 | ); 266 | inputPaths = ( 267 | ); 268 | name = "[CP] Embed Pods Frameworks"; 269 | outputPaths = ( 270 | ); 271 | runOnlyForDeploymentPostprocessing = 0; 272 | shellPath = /bin/sh; 273 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 274 | showEnvVarsInLog = 0; 275 | }; 276 | /* End PBXShellScriptBuildPhase section */ 277 | 278 | /* Begin PBXSourcesBuildPhase section */ 279 | 97C146EA1CF9000F007C117D /* Sources */ = { 280 | isa = PBXSourcesBuildPhase; 281 | buildActionMask = 2147483647; 282 | files = ( 283 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 284 | 97C146F31CF9000F007C117D /* main.m in Sources */, 285 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | /* End PBXSourcesBuildPhase section */ 290 | 291 | /* Begin PBXVariantGroup section */ 292 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 293 | isa = PBXVariantGroup; 294 | children = ( 295 | 97C146FB1CF9000F007C117D /* Base */, 296 | ); 297 | name = Main.storyboard; 298 | sourceTree = ""; 299 | }; 300 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 301 | isa = PBXVariantGroup; 302 | children = ( 303 | 97C147001CF9000F007C117D /* Base */, 304 | ); 305 | name = LaunchScreen.storyboard; 306 | sourceTree = ""; 307 | }; 308 | /* End PBXVariantGroup section */ 309 | 310 | /* Begin XCBuildConfiguration section */ 311 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 312 | isa = XCBuildConfiguration; 313 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 314 | buildSettings = { 315 | ALWAYS_SEARCH_USER_PATHS = NO; 316 | CLANG_ANALYZER_NONNULL = YES; 317 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 318 | CLANG_CXX_LIBRARY = "libc++"; 319 | CLANG_ENABLE_MODULES = YES; 320 | CLANG_ENABLE_OBJC_ARC = YES; 321 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 322 | CLANG_WARN_BOOL_CONVERSION = YES; 323 | CLANG_WARN_COMMA = YES; 324 | CLANG_WARN_CONSTANT_CONVERSION = YES; 325 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 326 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 327 | CLANG_WARN_EMPTY_BODY = YES; 328 | CLANG_WARN_ENUM_CONVERSION = YES; 329 | CLANG_WARN_INFINITE_RECURSION = YES; 330 | CLANG_WARN_INT_CONVERSION = YES; 331 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 333 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 334 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 335 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 336 | CLANG_WARN_STRICT_PROTOTYPES = YES; 337 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 338 | CLANG_WARN_UNREACHABLE_CODE = YES; 339 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 340 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 341 | COPY_PHASE_STRIP = NO; 342 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 343 | ENABLE_NS_ASSERTIONS = NO; 344 | ENABLE_STRICT_OBJC_MSGSEND = YES; 345 | GCC_C_LANGUAGE_STANDARD = gnu99; 346 | GCC_NO_COMMON_BLOCKS = YES; 347 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 348 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 349 | GCC_WARN_UNDECLARED_SELECTOR = YES; 350 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 351 | GCC_WARN_UNUSED_FUNCTION = YES; 352 | GCC_WARN_UNUSED_VARIABLE = YES; 353 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 354 | MTL_ENABLE_DEBUG_INFO = NO; 355 | SDKROOT = iphoneos; 356 | SUPPORTED_PLATFORMS = iphoneos; 357 | TARGETED_DEVICE_FAMILY = "1,2"; 358 | VALIDATE_PRODUCT = YES; 359 | }; 360 | name = Profile; 361 | }; 362 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 363 | isa = XCBuildConfiguration; 364 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 365 | buildSettings = { 366 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 367 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 368 | DEVELOPMENT_TEAM = 8YA3WTV6AF; 369 | ENABLE_BITCODE = NO; 370 | FRAMEWORK_SEARCH_PATHS = ( 371 | "$(inherited)", 372 | "$(PROJECT_DIR)/Flutter", 373 | ); 374 | INFOPLIST_FILE = Runner/Info.plist; 375 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 376 | LIBRARY_SEARCH_PATHS = ( 377 | "$(inherited)", 378 | "$(PROJECT_DIR)/Flutter", 379 | ); 380 | PRODUCT_BUNDLE_IDENTIFIER = com.flutterdev.blue; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | VERSIONING_SYSTEM = "apple-generic"; 383 | }; 384 | name = Profile; 385 | }; 386 | 97C147031CF9000F007C117D /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 389 | buildSettings = { 390 | ALWAYS_SEARCH_USER_PATHS = NO; 391 | CLANG_ANALYZER_NONNULL = YES; 392 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 393 | CLANG_CXX_LIBRARY = "libc++"; 394 | CLANG_ENABLE_MODULES = YES; 395 | CLANG_ENABLE_OBJC_ARC = YES; 396 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 397 | CLANG_WARN_BOOL_CONVERSION = YES; 398 | CLANG_WARN_COMMA = YES; 399 | CLANG_WARN_CONSTANT_CONVERSION = YES; 400 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 401 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 402 | CLANG_WARN_EMPTY_BODY = YES; 403 | CLANG_WARN_ENUM_CONVERSION = YES; 404 | CLANG_WARN_INFINITE_RECURSION = YES; 405 | CLANG_WARN_INT_CONVERSION = YES; 406 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 407 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 408 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 409 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 410 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 411 | CLANG_WARN_STRICT_PROTOTYPES = YES; 412 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 413 | CLANG_WARN_UNREACHABLE_CODE = YES; 414 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 415 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 416 | COPY_PHASE_STRIP = NO; 417 | DEBUG_INFORMATION_FORMAT = dwarf; 418 | ENABLE_STRICT_OBJC_MSGSEND = YES; 419 | ENABLE_TESTABILITY = YES; 420 | GCC_C_LANGUAGE_STANDARD = gnu99; 421 | GCC_DYNAMIC_NO_PIC = NO; 422 | GCC_NO_COMMON_BLOCKS = YES; 423 | GCC_OPTIMIZATION_LEVEL = 0; 424 | GCC_PREPROCESSOR_DEFINITIONS = ( 425 | "DEBUG=1", 426 | "$(inherited)", 427 | ); 428 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 429 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 430 | GCC_WARN_UNDECLARED_SELECTOR = YES; 431 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 432 | GCC_WARN_UNUSED_FUNCTION = YES; 433 | GCC_WARN_UNUSED_VARIABLE = YES; 434 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 435 | MTL_ENABLE_DEBUG_INFO = YES; 436 | ONLY_ACTIVE_ARCH = YES; 437 | SDKROOT = iphoneos; 438 | TARGETED_DEVICE_FAMILY = "1,2"; 439 | }; 440 | name = Debug; 441 | }; 442 | 97C147041CF9000F007C117D /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 445 | buildSettings = { 446 | ALWAYS_SEARCH_USER_PATHS = NO; 447 | CLANG_ANALYZER_NONNULL = YES; 448 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 449 | CLANG_CXX_LIBRARY = "libc++"; 450 | CLANG_ENABLE_MODULES = YES; 451 | CLANG_ENABLE_OBJC_ARC = YES; 452 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 453 | CLANG_WARN_BOOL_CONVERSION = YES; 454 | CLANG_WARN_COMMA = YES; 455 | CLANG_WARN_CONSTANT_CONVERSION = YES; 456 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 457 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 458 | CLANG_WARN_EMPTY_BODY = YES; 459 | CLANG_WARN_ENUM_CONVERSION = YES; 460 | CLANG_WARN_INFINITE_RECURSION = YES; 461 | CLANG_WARN_INT_CONVERSION = YES; 462 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 463 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 464 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 465 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 466 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 467 | CLANG_WARN_STRICT_PROTOTYPES = YES; 468 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 469 | CLANG_WARN_UNREACHABLE_CODE = YES; 470 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 471 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 472 | COPY_PHASE_STRIP = NO; 473 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 474 | ENABLE_NS_ASSERTIONS = NO; 475 | ENABLE_STRICT_OBJC_MSGSEND = YES; 476 | GCC_C_LANGUAGE_STANDARD = gnu99; 477 | GCC_NO_COMMON_BLOCKS = YES; 478 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 479 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 480 | GCC_WARN_UNDECLARED_SELECTOR = YES; 481 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 482 | GCC_WARN_UNUSED_FUNCTION = YES; 483 | GCC_WARN_UNUSED_VARIABLE = YES; 484 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 485 | MTL_ENABLE_DEBUG_INFO = NO; 486 | SDKROOT = iphoneos; 487 | SUPPORTED_PLATFORMS = iphoneos; 488 | TARGETED_DEVICE_FAMILY = "1,2"; 489 | VALIDATE_PRODUCT = YES; 490 | }; 491 | name = Release; 492 | }; 493 | 97C147061CF9000F007C117D /* Debug */ = { 494 | isa = XCBuildConfiguration; 495 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 496 | buildSettings = { 497 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 498 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 499 | DEVELOPMENT_TEAM = 8YA3WTV6AF; 500 | ENABLE_BITCODE = NO; 501 | FRAMEWORK_SEARCH_PATHS = ( 502 | "$(inherited)", 503 | "$(PROJECT_DIR)/Flutter", 504 | ); 505 | INFOPLIST_FILE = Runner/Info.plist; 506 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 507 | LIBRARY_SEARCH_PATHS = ( 508 | "$(inherited)", 509 | "$(PROJECT_DIR)/Flutter", 510 | ); 511 | PRODUCT_BUNDLE_IDENTIFIER = com.flutterdev.blue; 512 | PRODUCT_NAME = "$(TARGET_NAME)"; 513 | VERSIONING_SYSTEM = "apple-generic"; 514 | }; 515 | name = Debug; 516 | }; 517 | 97C147071CF9000F007C117D /* Release */ = { 518 | isa = XCBuildConfiguration; 519 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 520 | buildSettings = { 521 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 522 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 523 | DEVELOPMENT_TEAM = 8YA3WTV6AF; 524 | ENABLE_BITCODE = NO; 525 | FRAMEWORK_SEARCH_PATHS = ( 526 | "$(inherited)", 527 | "$(PROJECT_DIR)/Flutter", 528 | ); 529 | INFOPLIST_FILE = Runner/Info.plist; 530 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 531 | LIBRARY_SEARCH_PATHS = ( 532 | "$(inherited)", 533 | "$(PROJECT_DIR)/Flutter", 534 | ); 535 | PRODUCT_BUNDLE_IDENTIFIER = com.flutterdev.blue; 536 | PRODUCT_NAME = "$(TARGET_NAME)"; 537 | VERSIONING_SYSTEM = "apple-generic"; 538 | }; 539 | name = Release; 540 | }; 541 | /* End XCBuildConfiguration section */ 542 | 543 | /* Begin XCConfigurationList section */ 544 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 545 | isa = XCConfigurationList; 546 | buildConfigurations = ( 547 | 97C147031CF9000F007C117D /* Debug */, 548 | 97C147041CF9000F007C117D /* Release */, 549 | 249021D3217E4FDB00AE95B9 /* Profile */, 550 | ); 551 | defaultConfigurationIsVisible = 0; 552 | defaultConfigurationName = Release; 553 | }; 554 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 555 | isa = XCConfigurationList; 556 | buildConfigurations = ( 557 | 97C147061CF9000F007C117D /* Debug */, 558 | 97C147071CF9000F007C117D /* Release */, 559 | 249021D4217E4FDB00AE95B9 /* Profile */, 560 | ); 561 | defaultConfigurationIsVisible = 0; 562 | defaultConfigurationName = Release; 563 | }; 564 | /* End XCConfigurationList section */ 565 | }; 566 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 567 | } 568 | --------------------------------------------------------------------------------