Topic List
หลังจากติดตั้ง Flutter บน Macbook M1 pro ก็เกิดอาการ Exception: Error running pod install ตอนสั่ง flutter run บน iOS
ทางแก้ที่ลองแล้ว work คือ
1.Run คำสั่งในครั้งแรก (ครั้งเดียว)
sudo arch -x86_64 gem install ffi
2.ติดตั้ง pods
cd Project/ios arch -x86_64 pod install
จากคำสั่ง ดูเหมือนจะเป็นการติดตั้ง x86 แต่มันสามารถใช้งานได้ เลยไม่แน่ใจเหมือนกันว่าเป็นวิธีการแก้ปัญหาที่ถูกต้องไหม
ที่มา:
กำลังหาข้อมูลเกี่ยวกับการ build app with signed เพื่อส่งขึ้น Play Store
ทำตามขั้นตอนในเว็บ flutter.dev
ถ้ายังไม่มี java หรือ error ให้ลอง openjdk ก่อน
brew install openjdk export JAVA_HOME="/opt/homebrew/opt/openjdk/libexec/openjdk.jdk/Contents/Home" java --version
สร้าง key : ถ้ายังไม่มีการสร้างไฟล์ .jks ให้สร้างขึ้นมาก่อน
ดูข้อมูลในไฟล์ .jkskeytool -genkey -v -keystore /Users/name/appname.jks -keyalg RSA -keysize 2048 -validity 10000 -alias release
ดูข้อมูลในไฟล์ .apkkeytool -v -list -keystore appname.jks
keytool -printcert -jarfile appname.apk
#กำหนดการ keystore ไว้ใน app สร้างไฟล์ [project]/android/key.properties แล้ว copy code ด้านล่างไปใส่
storePassword=<password from previous step> keyPassword=<password from previous step> keyAlias=upload storeFile=<location of the key store file, such as /Users/<user name>/upload-keystore.jks>
คำเตือน เก็บรักษาไฟล์ key.properties ไว้ให้ดี อย่างส่งขึ้น git เด็ดขาด
กำหนดค่าเพื่อ signing ใน gradle
1.แก้ไขไฟล์ [project]/android/app/build.gradle
def keystoreProperties = new Properties() def keystorePropertiesFile = rootProject.file('key.properties') if (keystorePropertiesFile.exists()) { keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) }android { ... }
2.หา buildTypes
แทนที่ด้วยbuildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, // soflutter run --release
works. signingConfig signingConfigs.debug } }
signingConfigs { release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null storePassword keystoreProperties['storePassword'] } } buildTypes { release { signingConfig signingConfigs.release } }
Build
flutter build appbundle
ผลลัพท์ของการ build จะอยู่ที่
build/app/outputs/bundle/release/app-release.aab
ติดขั้นตอนอัพโหลดขึ้น play store
"Your Android App Bundle is signed with the wrong key. Ensure that your App Bundle is signed with the correct signing key and try again. Your App Bundle is expected to be signed with the certificate with fingerprint"
ลองหาทางแก้ไข ก็ไม่หาย แต่พอลองอัพหลายครั้ง ก็ยังขึ้น error แต่ปุ่มให้ SAVE สามารถใช้งานได้ ก็เลยผ่าน
ลองอัพ version ใหม่ ปรากฎว่า ไม่ขึ้น error
ที่มา:
import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:package_info/package_info.dart'; class AboutScreen extends StatefulWidget { static String routeName = "/about"; @override _AboutScreenState createState() => _AboutScreenState(); } class _AboutScreenState extends State<AboutScreen> { PackageInfo _packageInfo = PackageInfo( appName: 'Unknown', packageName: 'Unknown', version: 'Unknown', buildNumber: 'Unknown', ); //SharedPreferences.setMockInitialValues({}); @override initState() { super.initState(); _initPackageInfo(); } Future<void> _initPackageInfo() async { final PackageInfo info = await PackageInfo.fromPlatform(); log(info.toString()); setState(() { _packageInfo = info; }); } Widget _infoTile(String title, String subtitle) { return ListTile( title: Text(title), subtitle: Text(subtitle.isNotEmpty ? subtitle : 'Not set'), ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( // title: Text(widget.title), title: Text('About us'), ), body: Column( // mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ _infoTile('App name', _packageInfo.appName), _infoTile('Package name', _packageInfo.packageName), _infoTile('App version', _packageInfo.version), _infoTile('Build number', _packageInfo.buildNumber), ], ), ); } }
ที่มา
iOS: in ios/Runner/Info.plist
ขอสิทธิ์ Location
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key><true/> </dict>
ขอสิทธิ์ใช้กล้อง
<key>NSCameraUsageDescription</key> <string>Explanation on why the camera access is needed.</string>
ขอสิทธิ์ไมโครโฟน
<key>NSMicrophoneUsageDescription</key> <string>Flutter requires acess to microphone.</string>
Android: android/app/build.gradle
defaultConfig { minSdkVersion 21
Android: android/app/src/main/AndroidManifest.xml
<application> <provider android:name="com.pichillilorenzo.flutterinappwebview.InAppWebViewFileProvider" android:authorities="${applicationId}.flutterinappwebview.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILEPROVIDERPATHS" android:resource="@xml/provider_paths" /> </provider> </application>
Create file res/values/provider_paths.xml
<?xml version="1.0" encoding="utf-8"?> <paths> </paths>
main.dart
import 'package:permission_handler/permission_handler.dart'; Future main() async { WidgetsFlutterBinding.ensureInitialized(); await Permission.camera.request(); runApp(MyApp()); }
สิทธิ์อื่นดูได้จาก Enable camera for HTML inputs
ที่มา
Step 1. Create a new application. The main screen in which will be StatefulWidget. Which should implement the WidgetsBindingObserver interface. Next, we get the instance of WidgetBinding and add an observer to it.
class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver { @override void initState() { WidgetsBinding.instance.addObserver(this); super.initState(); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Flutter Tutorial Lifecycle'), ), body: Center(), ); } }
Step 2. Now we have the didChangeAppLifecycleState method available. In this example, we simply print a state change to the thermal.
@override void didChangeAppLifecycleState(AppLifecycleState state) { print('state = $state'); }
ที่มา Flutter App Lifecycle
เขียน Flutter App
Create new app
flutter create --org com.yourdomain appname
Android หากมี error gradle ให้แก้ไขไฟล์ android > gradle > gradle-wrapper.properties
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip
Set App signing team to your email
Open app using VSCode and run
Then build iodopen ios/Runner.xcworkspace
flutter build ios
In Runner / Targets/Runner -> select Team
If have already created a project: Change package name by add dependencies changeapppackagename: and run
apppackagename:main com.package.appnameflutter pub run change
Run in release mode
flutter run --release
Settings
- เปลี่ยนชื่อ App Icon
- Add permission: กำหนด Permission ด้วยนะ ไม่อย่างนั้นจะเปิด WebView เข้าเน็ตไม่ได้
iOS: แก้ไขไฟล์ ios/Runner/info.plist
<key>CFBundleName</key> <string>APP NAME</string> <key>io.flutter.embeddedviewspreview</key> <string>YES</string>
Android manifest: แก้ไขไฟล์ android/app/src/main/AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" /> <application android:label="APP NAME" >
macOS: in macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements
<key>com.apple.security.network.client</key> <true/>
App Icon:
File : pubspec.yaml
dependencies: ... flutter_launcher_icons: ^0.9.0
flutter_icons:<br /> image_path: "assets/icon/logo_192.png"<br /> android: true ios: true remove_alpha_ios: true
# dart run flutter_launcher_icons:main
เอาคำว่า "DEBUG" ของเธอคืนไป
ใส่ไว้ใน MaterialApp
debugShowCheckedModeBanner: false
Add dependencies แล้ว แต่ import package ไม่ได้
close project and re-open projectflutter packages get
Upgrade version iOS แล้วมองไม่เห็น device
ให้ดาวน์โหลดไฟล์จาก GitHub แล้วนำไฟล์มาวางไว้ที่ (~/Application/) Xcode app ใน path Contents/Developer/Platform/iPhoneOS.platform/DeviceSupport
แล้วก็ Flutter Clean
flutter clean
App Permission
หัวข้ออื่น
ที่มา
- มาลองสร้าง Flutter App กันเถอะ
- ประสบการณ์ Build flutter on iOS ครั้งแรก
- webview_flutter 2.0.2
- Different ways to change the status bar and navigation bar color (iOS and Android) in Flutter
- Flutter Launcher Icons
- How to use user-agent in webview-flutter Flutter?
- Flutter webview intercept and add headers to all requests
- Webview in flutter not working getting a platform error
- Flutter BottomNavigationBar not working with more than three items
น่าจะถึงเวลาที่ต้องมาเขียน App บน iOS เสียที มีงานรออยู่หลายชิ้นแล้ว ตั้งแต่ iMed@home, Green Smile, 1T1U และน่าจะมีตามมาอีกหลายงาน เช่น iMed@NCD Care
Set App to be a release mode (default is debug mode cannot run directly)
In VS Code Settings:
Tab User => Extensions/Dart & Flutter/Dart: Flutter Run Additional Args
or search "Flutter Run Additional Args"
Dart: Flutter Run Additional Args
Additional args to pass to the flutter run command.
Add Item --release
In command line
You can Run your application in Release Mode easily in your terminal using :
flutter run --release
And it will switch to Release Mode .
But if you don't want to run your app , just want to build your apk or ipa , Use :
flutter build --release
In X-Code
You can specify to build for ios by using flutter build ios
Follow these 3 steps:
cd project open ios/Runner.xcworkspace
- Open your Flutter project in Xcode.
- Top Bar Product > Scheme > Edit Scheme
- Build Configuration - Select Release
Note: Release type flutter app is valid for 7 days on iOS devices.
ที่มา