Committed by
GitHub
Merge pull request #798 from Spyy004/master
feat: Scanner with overlay screen added
Showing
7 changed files
with
243 additions
and
232 deletions
| @@ -155,7 +155,7 @@ | @@ -155,7 +155,7 @@ | ||
| 155 | 97C146E61CF9000F007C117D /* Project object */ = { | 155 | 97C146E61CF9000F007C117D /* Project object */ = { |
| 156 | isa = PBXProject; | 156 | isa = PBXProject; |
| 157 | attributes = { | 157 | attributes = { |
| 158 | - LastUpgradeCheck = 1300; | 158 | + LastUpgradeCheck = 1430; |
| 159 | ORGANIZATIONNAME = ""; | 159 | ORGANIZATIONNAME = ""; |
| 160 | TargetAttributes = { | 160 | TargetAttributes = { |
| 161 | 97C146ED1CF9000F007C117D = { | 161 | 97C146ED1CF9000F007C117D = { |
| @@ -51,5 +51,10 @@ | @@ -51,5 +51,10 @@ | ||
| 51 | </array> | 51 | </array> |
| 52 | <key>UIViewControllerBasedStatusBarAppearance</key> | 52 | <key>UIViewControllerBasedStatusBarAppearance</key> |
| 53 | <false/> | 53 | <false/> |
| 54 | + <key>NSCameraUsageDescription</key> | ||
| 55 | + <string>This app needs camera access to scan QR codes</string> | ||
| 56 | + | ||
| 57 | + <key>NSPhotoLibraryUsageDescription</key> | ||
| 58 | + <string>This app needs photos access to get QR code from photo library</string> | ||
| 54 | </dict> | 59 | </dict> |
| 55 | </plist> | 60 | </plist> |
| @@ -6,6 +6,7 @@ import 'package:mobile_scanner_example/barcode_scanner_returning_image.dart'; | @@ -6,6 +6,7 @@ import 'package:mobile_scanner_example/barcode_scanner_returning_image.dart'; | ||
| 6 | import 'package:mobile_scanner_example/barcode_scanner_window.dart'; | 6 | import 'package:mobile_scanner_example/barcode_scanner_window.dart'; |
| 7 | import 'package:mobile_scanner_example/barcode_scanner_without_controller.dart'; | 7 | import 'package:mobile_scanner_example/barcode_scanner_without_controller.dart'; |
| 8 | import 'package:mobile_scanner_example/barcode_scanner_zoom.dart'; | 8 | import 'package:mobile_scanner_example/barcode_scanner_zoom.dart'; |
| 9 | +import 'package:mobile_scanner_example/mobile_scanner_overlay.dart'; | ||
| 9 | 10 | ||
| 10 | void main() => runApp(const MaterialApp(home: MyHome())); | 11 | void main() => runApp(const MaterialApp(home: MyHome())); |
| 11 | 12 | ||
| @@ -95,6 +96,16 @@ class MyHome extends StatelessWidget { | @@ -95,6 +96,16 @@ class MyHome extends StatelessWidget { | ||
| 95 | }, | 96 | }, |
| 96 | child: const Text('MobileScanner pageView'), | 97 | child: const Text('MobileScanner pageView'), |
| 97 | ), | 98 | ), |
| 99 | + ElevatedButton( | ||
| 100 | + onPressed: () { | ||
| 101 | + Navigator.of(context).push( | ||
| 102 | + MaterialPageRoute( | ||
| 103 | + builder: (context) => BarcodeScannerWithOverlay(), | ||
| 104 | + ), | ||
| 105 | + ); | ||
| 106 | + }, | ||
| 107 | + child: const Text('MobileScanner with Overlay'), | ||
| 108 | + ), | ||
| 98 | ], | 109 | ], |
| 99 | ), | 110 | ), |
| 100 | ), | 111 | ), |
| 1 | -//TODO: Create example with scanner overlay | ||
| 2 | - | ||
| 3 | -// import 'dart:ui'; | ||
| 4 | -// | ||
| 5 | -// import 'package:flutter/material.dart'; | ||
| 6 | -// import 'package:mobile_scanner/mobile_scanner.dart'; | ||
| 7 | -// | ||
| 8 | -// void main() { | ||
| 9 | -// runApp(const AnalyzeView()); | ||
| 10 | -// } | ||
| 11 | -// | ||
| 12 | -// class AnalyzeView extends StatefulWidget { | ||
| 13 | -// const AnalyzeView({Key? key}) : super(key: key); | ||
| 14 | -// | ||
| 15 | -// @override | ||
| 16 | -// _AnalyzeViewState createState() => _AnalyzeViewState(); | ||
| 17 | -// } | ||
| 18 | -// | ||
| 19 | -// class _AnalyzeViewState extends State<AnalyzeView> | ||
| 20 | -// with SingleTickerProviderStateMixin { | ||
| 21 | -// List<Offset> points = []; | ||
| 22 | -// | ||
| 23 | -// // CameraController cameraController = CameraController(context, width: 320, height: 150); | ||
| 24 | -// | ||
| 25 | -// String? barcode; | ||
| 26 | -// | ||
| 27 | -// @override | ||
| 28 | -// Widget build(BuildContext context) { | ||
| 29 | -// return MaterialApp( | ||
| 30 | -// home: Scaffold( | ||
| 31 | -// body: Builder(builder: (context) { | ||
| 32 | -// return Stack( | ||
| 33 | -// children: [ | ||
| 34 | -// MobileScanner( | ||
| 35 | -// // fitScreen: false, | ||
| 36 | -// // controller: cameraController, | ||
| 37 | -// onDetect: (barcode, args) { | ||
| 38 | -// if (this.barcode != barcode.rawValue) { | ||
| 39 | -// this.barcode = barcode.rawValue; | ||
| 40 | -// if (barcode.corners != null) { | ||
| 41 | -// ScaffoldMessenger.of(context).showSnackBar(SnackBar( | ||
| 42 | -// content: Text(barcode.rawValue), | ||
| 43 | -// duration: const Duration(milliseconds: 200), | ||
| 44 | -// animation: null, | ||
| 45 | -// )); | ||
| 46 | -// setState(() { | ||
| 47 | -// final List<Offset> points = []; | ||
| 48 | -// // double factorWidth = args.size.width / 520; | ||
| 49 | -// // double factorHeight = wanted / args.size.height; | ||
| 50 | -// final size = MediaQuery.of(context).devicePixelRatio; | ||
| 51 | -// debugPrint('Size: ${barcode.corners}'); | ||
| 52 | -// for (var point in barcode.corners!) { | ||
| 53 | -// final adjustedWith = point.dx; | ||
| 54 | -// final adjustedHeight = point.dy; | ||
| 55 | -// points.add( | ||
| 56 | -// Offset(adjustedWith / size, adjustedHeight / size)); | ||
| 57 | -// // points.add(Offset((point.dx ) / size, | ||
| 58 | -// // (point.dy) / size)); | ||
| 59 | -// // final differenceWidth = (args.wantedSize!.width - args.size.width) / 2; | ||
| 60 | -// // final differenceHeight = (args.wantedSize!.height - args.size.height) / 2; | ||
| 61 | -// // points.add(Offset((point.dx + differenceWidth) / size, | ||
| 62 | -// // (point.dy + differenceHeight) / size)); | ||
| 63 | -// } | ||
| 64 | -// this.points = points; | ||
| 65 | -// }); | ||
| 66 | -// } | ||
| 67 | -// } | ||
| 68 | -// // Default 640 x480 | ||
| 69 | -// }), | ||
| 70 | -// CustomPaint( | ||
| 71 | -// painter: OpenPainter(points), | ||
| 72 | -// ), | ||
| 73 | -// // Container( | ||
| 74 | -// // alignment: Alignment.bottomCenter, | ||
| 75 | -// // margin: EdgeInsets.only(bottom: 80.0), | ||
| 76 | -// // child: IconButton( | ||
| 77 | -// // icon: ValueListenableBuilder( | ||
| 78 | -// // valueListenable: cameraController.torchState, | ||
| 79 | -// // builder: (context, state, child) { | ||
| 80 | -// // final color = | ||
| 81 | -// // state == TorchState.off ? Colors.grey : Colors.white; | ||
| 82 | -// // return Icon(Icons.bolt, color: color); | ||
| 83 | -// // }, | ||
| 84 | -// // ), | ||
| 85 | -// // iconSize: 32.0, | ||
| 86 | -// // onPressed: () => cameraController.torch(), | ||
| 87 | -// // ), | ||
| 88 | -// // ), | ||
| 89 | -// ], | ||
| 90 | -// ); | ||
| 91 | -// }), | ||
| 92 | -// ), | ||
| 93 | -// ); | ||
| 94 | -// } | ||
| 95 | -// | ||
| 96 | -// @override | ||
| 97 | -// void dispose() { | ||
| 98 | -// // cameraController.dispose(); | ||
| 99 | -// super.dispose(); | ||
| 100 | -// } | ||
| 101 | -// | ||
| 102 | -// void display(Barcode barcode) { | ||
| 103 | -// Navigator.of(context).popAndPushNamed('display', arguments: barcode); | ||
| 104 | -// } | ||
| 105 | -// } | ||
| 106 | -// | ||
| 107 | -// class OpenPainter extends CustomPainter { | ||
| 108 | -// final List<Offset> points; | ||
| 109 | -// | ||
| 110 | -// OpenPainter(this.points); | ||
| 111 | -// @override | ||
| 112 | -// void paint(Canvas canvas, Size size) { | ||
| 113 | -// var paint1 = Paint() | ||
| 114 | -// ..color = const Color(0xff63aa65) | ||
| 115 | -// ..strokeWidth = 10; | ||
| 116 | -// //draw points on canvas | ||
| 117 | -// canvas.drawPoints(PointMode.points, points, paint1); | ||
| 118 | -// } | ||
| 119 | -// | ||
| 120 | -// @override | ||
| 121 | -// bool shouldRepaint(CustomPainter oldDelegate) => true; | ||
| 122 | -// } | ||
| 123 | -// | ||
| 124 | -// class OpacityCurve extends Curve { | ||
| 125 | -// @override | ||
| 126 | -// double transform(double t) { | ||
| 127 | -// if (t < 0.1) { | ||
| 128 | -// return t * 10; | ||
| 129 | -// } else if (t <= 0.9) { | ||
| 130 | -// return 1.0; | ||
| 131 | -// } else { | ||
| 132 | -// return (1.0 - t) * 10; | ||
| 133 | -// } | ||
| 134 | -// } | ||
| 135 | -// } | ||
| 136 | -// | ||
| 137 | -// // import 'package:flutter/material.dart'; | ||
| 138 | -// // import 'package:flutter/rendering.dart'; | ||
| 139 | -// // import 'package:mobile_scanner/mobile_scanner.dart'; | ||
| 140 | -// // | ||
| 141 | -// // void main() { | ||
| 142 | -// // debugPaintSizeEnabled = false; | ||
| 143 | -// // runApp(HomePage()); | ||
| 144 | -// // } | ||
| 145 | -// // | ||
| 146 | -// // class HomePage extends StatefulWidget { | ||
| 147 | -// // @override | ||
| 148 | -// // HomeState createState() => HomeState(); | ||
| 149 | -// // } | ||
| 150 | -// // | ||
| 151 | -// // class HomeState extends State<HomePage> { | ||
| 152 | -// // @override | ||
| 153 | -// // Widget build(BuildContext context) { | ||
| 154 | -// // return MaterialApp(home: MyApp()); | ||
| 155 | -// // } | ||
| 156 | -// // } | ||
| 157 | -// // | ||
| 158 | -// // class MyApp extends StatefulWidget { | ||
| 159 | -// // @override | ||
| 160 | -// // _MyAppState createState() => _MyAppState(); | ||
| 161 | -// // } | ||
| 162 | -// // | ||
| 163 | -// // class _MyAppState extends State<MyApp> { | ||
| 164 | -// // String? qr; | ||
| 165 | -// // bool camState = false; | ||
| 166 | -// // | ||
| 167 | -// // @override | ||
| 168 | -// // initState() { | ||
| 169 | -// // super.initState(); | ||
| 170 | -// // } | ||
| 171 | -// // | ||
| 172 | -// // @override | ||
| 173 | -// // Widget build(BuildContext context) { | ||
| 174 | -// // return Scaffold( | ||
| 175 | -// // appBar: AppBar( | ||
| 176 | -// // title: Text('Plugin example app'), | ||
| 177 | -// // ), | ||
| 178 | -// // body: Center( | ||
| 179 | -// // child: Column( | ||
| 180 | -// // crossAxisAlignment: CrossAxisAlignment.center, | ||
| 181 | -// // mainAxisAlignment: MainAxisAlignment.center, | ||
| 182 | -// // children: <Widget>[ | ||
| 183 | -// // Expanded( | ||
| 184 | -// // child: camState | ||
| 185 | -// // ? Center( | ||
| 186 | -// // child: SizedBox( | ||
| 187 | -// // width: 300.0, | ||
| 188 | -// // height: 600.0, | ||
| 189 | -// // child: MobileScanner( | ||
| 190 | -// // onError: (context, error) => Text( | ||
| 191 | -// // error.toString(), | ||
| 192 | -// // style: TextStyle(color: Colors.red), | ||
| 193 | -// // ), | ||
| 194 | -// // qrCodeCallback: (code) { | ||
| 195 | -// // setState(() { | ||
| 196 | -// // qr = code; | ||
| 197 | -// // }); | ||
| 198 | -// // }, | ||
| 199 | -// // child: Container( | ||
| 200 | -// // decoration: BoxDecoration( | ||
| 201 | -// // color: Colors.transparent, | ||
| 202 | -// // border: Border.all( | ||
| 203 | -// // color: Colors.orange, | ||
| 204 | -// // width: 10.0, | ||
| 205 | -// // style: BorderStyle.solid), | ||
| 206 | -// // ), | ||
| 207 | -// // ), | ||
| 208 | -// // ), | ||
| 209 | -// // ), | ||
| 210 | -// // ) | ||
| 211 | -// // : Center(child: Text("Camera inactive"))), | ||
| 212 | -// // Text("QRCODE: $qr"), | ||
| 213 | -// // ], | ||
| 214 | -// // ), | ||
| 215 | -// // ), | ||
| 216 | -// // floatingActionButton: FloatingActionButton( | ||
| 217 | -// // child: Text( | ||
| 218 | -// // "press me", | ||
| 219 | -// // textAlign: TextAlign.center, | ||
| 220 | -// // ), | ||
| 221 | -// // onPressed: () { | ||
| 222 | -// // setState(() { | ||
| 223 | -// // camState = !camState; | ||
| 224 | -// // }); | ||
| 225 | -// // }), | ||
| 226 | -// // ); | ||
| 227 | -// // } | ||
| 228 | -// // } | 1 | +import 'package:flutter/material.dart'; |
| 2 | +import 'package:mobile_scanner/mobile_scanner.dart'; | ||
| 3 | +import 'package:mobile_scanner_example/scanner_error_widget.dart'; | ||
| 4 | + | ||
| 5 | +class BarcodeScannerWithOverlay extends StatefulWidget { | ||
| 6 | + @override | ||
| 7 | + _BarcodeScannerWithOverlayState createState() => | ||
| 8 | + _BarcodeScannerWithOverlayState(); | ||
| 9 | +} | ||
| 10 | + | ||
| 11 | +class _BarcodeScannerWithOverlayState extends State<BarcodeScannerWithOverlay> { | ||
| 12 | + String overlayText = "Please scan QR Code"; | ||
| 13 | + bool camStarted = false; | ||
| 14 | + | ||
| 15 | + final ValueNotifier<bool> torchStateNotifier = ValueNotifier<bool>(false); | ||
| 16 | + | ||
| 17 | + final MobileScannerController controller = MobileScannerController( | ||
| 18 | + formats: const [BarcodeFormat.qrCode], | ||
| 19 | + autoStart: false, | ||
| 20 | + ); | ||
| 21 | + | ||
| 22 | + @override | ||
| 23 | + void dispose() { | ||
| 24 | + controller.dispose(); | ||
| 25 | + super.dispose(); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + void startCamera() { | ||
| 29 | + try { | ||
| 30 | + setState(() { | ||
| 31 | + camStarted = !camStarted; | ||
| 32 | + controller.start(); | ||
| 33 | + }); | ||
| 34 | + } on Exception catch (e) { | ||
| 35 | + ScaffoldMessenger.of(context).showSnackBar( | ||
| 36 | + SnackBar( | ||
| 37 | + content: Text('Something went wrong! $e'), | ||
| 38 | + backgroundColor: Colors.red, | ||
| 39 | + ), | ||
| 40 | + ); | ||
| 41 | + } | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | + void onBarcodeDetect(BarcodeCapture barcodeCapture) { | ||
| 45 | + final barcode = barcodeCapture.barcodes.last; | ||
| 46 | + setState(() { | ||
| 47 | + overlayText = barcodeCapture.barcodes.last.displayValue ?? | ||
| 48 | + barcode.rawValue ?? | ||
| 49 | + 'Barcode has no displayable value'; | ||
| 50 | + }); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @override | ||
| 54 | + Widget build(BuildContext context) { | ||
| 55 | + final scanWindow = Rect.fromCenter( | ||
| 56 | + center: MediaQuery.of(context).size.center(Offset.zero), | ||
| 57 | + width: 200, | ||
| 58 | + height: 200, | ||
| 59 | + ); | ||
| 60 | + | ||
| 61 | + return Scaffold( | ||
| 62 | + appBar: AppBar( | ||
| 63 | + title: const Text('Scanner with Overlay Example app'), | ||
| 64 | + ), | ||
| 65 | + body: Center( | ||
| 66 | + child: Column( | ||
| 67 | + mainAxisAlignment: MainAxisAlignment.center, | ||
| 68 | + children: <Widget>[ | ||
| 69 | + Expanded( | ||
| 70 | + child: camStarted | ||
| 71 | + ? Stack( | ||
| 72 | + fit: StackFit.expand, | ||
| 73 | + children: [ | ||
| 74 | + Center( | ||
| 75 | + child: MobileScanner( | ||
| 76 | + fit: BoxFit.contain, | ||
| 77 | + onDetect: onBarcodeDetect, | ||
| 78 | + overlay: Padding( | ||
| 79 | + padding: const EdgeInsets.all(16.0), | ||
| 80 | + child: Align( | ||
| 81 | + alignment: Alignment.bottomCenter, | ||
| 82 | + child: Opacity( | ||
| 83 | + opacity: 0.7, | ||
| 84 | + child: Text( | ||
| 85 | + overlayText, | ||
| 86 | + style: const TextStyle( | ||
| 87 | + backgroundColor: Colors.black26, | ||
| 88 | + color: Colors.white, | ||
| 89 | + fontWeight: FontWeight.bold, | ||
| 90 | + fontSize: 24, | ||
| 91 | + overflow: TextOverflow.ellipsis, | ||
| 92 | + ), | ||
| 93 | + maxLines: 1, | ||
| 94 | + ), | ||
| 95 | + ), | ||
| 96 | + ), | ||
| 97 | + ), | ||
| 98 | + controller: controller, | ||
| 99 | + scanWindow: scanWindow, | ||
| 100 | + errorBuilder: (context, error, child) { | ||
| 101 | + return ScannerErrorWidget(error: error); | ||
| 102 | + }, | ||
| 103 | + ), | ||
| 104 | + ), | ||
| 105 | + CustomPaint( | ||
| 106 | + painter: ScannerOverlay(scanWindow), | ||
| 107 | + ), | ||
| 108 | + Padding( | ||
| 109 | + padding: const EdgeInsets.all(16.0), | ||
| 110 | + child: Align( | ||
| 111 | + alignment: Alignment.bottomCenter, | ||
| 112 | + child: Row( | ||
| 113 | + mainAxisAlignment: MainAxisAlignment.spaceEvenly, | ||
| 114 | + children: [ | ||
| 115 | + ValueListenableBuilder<bool>( | ||
| 116 | + valueListenable: torchStateNotifier, | ||
| 117 | + builder: (context, isTorchOn, child) { | ||
| 118 | + return IconButton( | ||
| 119 | + onPressed: () { | ||
| 120 | + controller.toggleTorch(); | ||
| 121 | + torchStateNotifier.value = | ||
| 122 | + !torchStateNotifier.value; | ||
| 123 | + }, | ||
| 124 | + icon: Icon( | ||
| 125 | + Icons.flashlight_on, | ||
| 126 | + color: isTorchOn | ||
| 127 | + ? Colors.yellow | ||
| 128 | + : Colors.black, | ||
| 129 | + ), | ||
| 130 | + ); | ||
| 131 | + }, | ||
| 132 | + ), | ||
| 133 | + IconButton( | ||
| 134 | + onPressed: () => controller.switchCamera(), | ||
| 135 | + icon: const Icon( | ||
| 136 | + Icons.cameraswitch_rounded, | ||
| 137 | + color: Colors.white, | ||
| 138 | + ), | ||
| 139 | + ), | ||
| 140 | + ], | ||
| 141 | + ), | ||
| 142 | + ), | ||
| 143 | + ), | ||
| 144 | + ], | ||
| 145 | + ) | ||
| 146 | + : const Center( | ||
| 147 | + child: Text("Tap on Camera to activate QR Scanner"), | ||
| 148 | + ), | ||
| 149 | + ), | ||
| 150 | + ], | ||
| 151 | + ), | ||
| 152 | + ), | ||
| 153 | + floatingActionButton: camStarted | ||
| 154 | + ? null | ||
| 155 | + : FloatingActionButton( | ||
| 156 | + child: const Icon( | ||
| 157 | + Icons.camera_alt, | ||
| 158 | + ), | ||
| 159 | + onPressed: () { | ||
| 160 | + startCamera(); | ||
| 161 | + }, | ||
| 162 | + ), | ||
| 163 | + ); | ||
| 164 | + } | ||
| 165 | +} | ||
| 166 | + | ||
| 167 | +class ScannerOverlay extends CustomPainter { | ||
| 168 | + ScannerOverlay(this.scanWindow); | ||
| 169 | + | ||
| 170 | + final Rect scanWindow; | ||
| 171 | + final double borderRadius = 12.0; | ||
| 172 | + | ||
| 173 | + @override | ||
| 174 | + void paint(Canvas canvas, Size size) { | ||
| 175 | + final backgroundPath = Path()..addRect(Rect.largest); | ||
| 176 | + final cutoutPath = Path() | ||
| 177 | + ..addRRect( | ||
| 178 | + RRect.fromRectAndCorners( | ||
| 179 | + scanWindow, | ||
| 180 | + topLeft: Radius.circular(borderRadius), | ||
| 181 | + topRight: Radius.circular(borderRadius), | ||
| 182 | + bottomLeft: Radius.circular(borderRadius), | ||
| 183 | + bottomRight: Radius.circular(borderRadius), | ||
| 184 | + ), | ||
| 185 | + ); | ||
| 186 | + | ||
| 187 | + final backgroundPaint = Paint() | ||
| 188 | + ..color = Colors.black.withOpacity(0.5) | ||
| 189 | + ..style = PaintingStyle.fill | ||
| 190 | + ..blendMode = BlendMode.dstOut; | ||
| 191 | + | ||
| 192 | + final backgroundWithCutout = Path.combine( | ||
| 193 | + PathOperation.difference, | ||
| 194 | + backgroundPath, | ||
| 195 | + cutoutPath, | ||
| 196 | + ); | ||
| 197 | + | ||
| 198 | + // Create a Paint object for the white border | ||
| 199 | + final borderPaint = Paint() | ||
| 200 | + ..color = Colors.white | ||
| 201 | + ..style = PaintingStyle.stroke | ||
| 202 | + ..strokeWidth = 4.0; // Adjust the border width as needed | ||
| 203 | + | ||
| 204 | + // Calculate the border rectangle with rounded corners | ||
| 205 | +// Adjust the radius as needed | ||
| 206 | + final borderRect = RRect.fromRectAndCorners( | ||
| 207 | + scanWindow, | ||
| 208 | + topLeft: Radius.circular(borderRadius), | ||
| 209 | + topRight: Radius.circular(borderRadius), | ||
| 210 | + bottomLeft: Radius.circular(borderRadius), | ||
| 211 | + bottomRight: Radius.circular(borderRadius), | ||
| 212 | + ); | ||
| 213 | + | ||
| 214 | + // Draw the white border | ||
| 215 | + canvas.drawPath(backgroundWithCutout, backgroundPaint); | ||
| 216 | + canvas.drawRRect(borderRect, borderPaint); | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + @override | ||
| 220 | + bool shouldRepaint(covariant CustomPainter oldDelegate) { | ||
| 221 | + return false; | ||
| 222 | + } | ||
| 223 | +} |
| @@ -202,7 +202,7 @@ | @@ -202,7 +202,7 @@ | ||
| 202 | isa = PBXProject; | 202 | isa = PBXProject; |
| 203 | attributes = { | 203 | attributes = { |
| 204 | LastSwiftUpdateCheck = 0920; | 204 | LastSwiftUpdateCheck = 0920; |
| 205 | - LastUpgradeCheck = 1300; | 205 | + LastUpgradeCheck = 1430; |
| 206 | ORGANIZATIONNAME = ""; | 206 | ORGANIZATIONNAME = ""; |
| 207 | TargetAttributes = { | 207 | TargetAttributes = { |
| 208 | 33CC10EC2044A3C60003C045 = { | 208 | 33CC10EC2044A3C60003C045 = { |
-
Please register or login to post a comment