How to obfuscate Flutter apps? - flutter

Flutter's wiki mentions obfuscation is an opt-in in release mode.
And yet, the flutter build command has no relevant option - see:
flutter help -v build apk
Am I missing something here?
Did they make obfuscation the default?
Is obfuscation even relevant for flutter?
Any pointers on this would be very appreciated.

Obfuscation is needed - a flutter app knows its function names, which can be shown using Dart's StackTrace class. There's under-tested support for obfuscation. To enable it:
For Android:
Add to the file [ProjectRoot]/android/gradle.properties :
extra-gen-snapshot-options=--obfuscate
For iOS:
First, edit [FlutterRoot]/packages/flutter_tools/bin/xcode_backend.sh:
Locate the build aot call, and add a flag to it,
${extra_gen_snapshot_options_or_none}
defined as:
local extra_gen_snapshot_options_or_none=""
if [[ -n "$EXTRA_GEN_SNAPSHOT_OPTIONS" ]]; then
extra_gen_snapshot_options_or_none="--extra-gen-snapshot-options=$EXTRA_GEN_SNAPSHOT_OPTIONS"
fi
To apply your changes, in [FlutterRoot], run
git commit -am "Enable obfuscation on iOS"
flutter
(Running "flutter" after the commit rebuilds flutter tools.)
Next, in your project, add following to [ProjectRoot]/ios/Flutter/Release.xcconfig file:
EXTRA_GEN_SNAPSHOT_OPTIONS=--obfuscate
PS: Haven't tried the --save-obfuscation-map flag mentioned at https://github.com/dart-lang/sdk/issues/30524
Again, obfuscation isn't very well tested, as mentioned by #mraleph.

AppBundle (recommended):
Without splitting:
flutter build appbundle --obfuscate --split-debug-info=/<directory>
Splitting:
flutter build appbundle --target-platform android-arm,android-arm64,android-x64 --obfuscate --split-debug-info=/<directory>
APK:
Without splitting:
flutter build apk --obfuscate --split-debug-info=/<directory>
Splitting:
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi --obfuscate --split-debug-info=/<directory>
PS: About Splitting:
By default, fat apk contains arm v7, arm v8 and x64 which increases apk size, which you don't want to. So, when you split it, you have separate binaries which you can upload on the store and thus reducing the size of the apk that a user would need to download.

All the above answers are correct, but no answer tells you that we need to add a relative path or directory path while generating build.
Example using Relative Path:
flutter build apk --obfuscate --split-debug-info=./ProjectFolderName/debug
Example using Folder Path:
flutter build apk --obfuscate --split-debug-info=/Users/apple/Desktop/items/debug
The above command will generate a build inside the given project directory, it will create a new folder called ProjectFolderName or 'debug' on the respective command, and there you can find the release build.

https://flutter.dev/docs/deployment/obfuscateRefer this link for more info
Note: Flutter’s code obfuscation, Supported as of Flutter 1.16.2.

For Android the process is pretty clear from the doc at https://flutter.dev/docs/deployment/obfuscate. For Example:
export version=1.0.0
flutter build apk --release --shrink --obfuscate --split-debug-info=misc/mapping/${version}
Several files will be created such as misc/mapping/1.0.0/app.android-arm64.symbols (which you'll likely want to keep in VCS)
For iOS it's a bit less obvious since you often use the Xcode menu: Product > Archive
make an obfuscated build for iOS
flutter build ios --release --obfuscate --split-debug-info=misc/mapping/${version}
it creates file misc/mapping/1.0.0/app.ios-arm64.symbols
This will also modify ios/Flutter/Generated.xcconfig to include
DART_OBFUSCATION=true
SPLIT_DEBUG_INFO=misc/mapping/1.0.0
Use Xcode menu: Product > Archive which will uses Release.xcconfig which includes updated Generated.xcconfig
#include "Generated.xcconfig"
So your uploaded Archive will now be obfuscated (you don't need to make changes to Release.xcconfig)
See also - https://github.com/flutter/flutter/issues/64626#issuecomment-736081173

At the moment obfuscation is not directly exposed via the flutter CLI.
You can try to explicitly pass arguements to the gen_snapshot like this:
flutter build --extra-gen-snapshot-options=--obfuscate,--save-obfuscation-map=build/symbols.json --release
Note: that obfuscation support is not very well tested and might not work at the moment.

For iOS edit ios/Flutter/Release.xcconfig
This file should contain something like
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
If you check Generated.xcconfig there is a line DART_OBFUSCATION=false
So add opposite to the end of the Release.xcconfig file to override:
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
DART_OBFUSCATION=true
SPLIT_DEBUG_INFO=obj_maps
You can optionally add TREE_SHAKE_ICONS=true here to tree-shake icons as well

Related

How to use --dart-define in a Flutter app embdedded in Android

I'm Embedding a Flutter app as a module within an existing Android app (https://flutter.dev/docs/development/add-to-app/android/project-setup) and would like to know if/how I can use "--dart-define" to define compile-time constants. Tried using ./gradlew -Ddart-define=myVal=Value without any luck.
When building a typical Flutter app I would use the flutter command. In my case I'm continuing to use gradlew to build my app and it's unclear how to pass in --dart-define constants.
In android studio you may edit running configuration (press drop-down near "run" button -> "Edit configurations...") and define variables there ("Additional run args:" row):
--dart-define="http_serv=http://10.0.2.2:42627/" --dart-define="websocket=ws://10.0.2.2:42627/websocket"
Getting variable in code:
final checkArgs = String.fromEnvironment('http_serv', defaultValue: '');
If your project depends on the Android Archive (AAR).
You can pass the dart-defines in the command line.
flutter build aar --dart-define=myVal=Value
If your project depends on the module’s source code.
You can set dart-defines in gradle.properties in your android host project directory (or in yourHostProject/yourFlutter/.android/Flutter/ directory).
--dart-define=myVal=Value
Explanation
.android/Flutter/build.gradle script executes "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" script. When the flutter.gradle is executed, your dart files are compiled into naitive code.
flutter.gradle loads dart-defines from the .android/Flutter project instance (flutter.gradle#731-L734) and then, use it ( flutter.gradle#L1091-L1093).
To set the project instance value, you add --dart-define=myVal=Value into gradle.properties. (If you have multiple gradle.properties files, consider configuration order(Gradle properties in Gradle Docs).

How Can I disable minify for flutter web release build [duplicate]

flutter build web will build my flutter app with obfuscation and minification.
I want my error stack to be readable though.
How should I modify the command?
Try:
flutter build web --profile --dart-define=Dart2jsOptimization=O0
See:
https://github.com/flutter/flutter/blob/720dff6a94bd054e82ec4bf84b5cb802bbc52ddd/packages/flutter_tools/lib/src/build_system/targets/web.dart#L238-L239
There's an issue on github for this feature, feel free to upvote ;)
https://github.com/flutter/flutter/issues/96283
This is a old post, but I found the answer.
If you build the app with this line:
flutter build web --profile --source-maps
Then when you print a stacktrace, you'll get something like this:
Exception: Hello
at Object.wrapException (js_helper.dart:1123:37)
at _MyHomePageState__incrementCounter_closure.call$0 (main.dart:64:7)
at _MyHomePageState.setState$1 (framework.dart:1114:28)
at _MyHomePageState._incrementCounter$0 (main.dart:57:5)
at tear_off.<anonymous> (js_helper.dart:2099:9)
at _InkResponseState.handleTap$0 (framework.dart:909:26)
at tear_off.<anonymous> (js_helper.dart:2099:9)
at TapGestureRecognizer.invokeCallback$1$3$debugReport (recognizer.dart:253:16)
at TapGestureRecognizer.invokeCallback$2 (recognizer.dart:239:6)
at TapGestureRecognizer.handleTapUp$2$down$up (tap.dart:627:11)
If you use --source-maps with a release build, you will still get the dart file and line number, but the class/method names in the stacktrace will be obfuscated.
And, if you copy the lib directory into the root of built web directory, it will display the source code when you click on the dart file/line number in the stacktrace. Also, you can set breakpoints in the dart code, just like you can do when you do flutter run web.
The only way I have found to do this is to use flutter run -d chrome. We would then need to locate where the files on disk are located.

How to use libflutter_linux_glfw.so file and related files from out/host_debug of flutter engine

I followed instructions from Setting up the Engine development to build the flutter engine. Purpose of this was to use the texture support from Texture support for glfw. I could compile the flutter engine.
Next I wanted to use this engine and develop Texture based application. While compiling using the following command, I see that libflutter_linux_glfw.so and other platform files are copied from flutter/bin/cache/artifacts/engine.
flutter build linux
I added the dependency_overrides to pubspec.yaml as follows. But, no luck.
dependency_overrides:
sky_engine:
path: <base folder of engine>/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine
sky_services:
path: <base folder of engine>/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services
Looking forward for the suggestions on the changes required to use files from engine/src/out/host_debug_unopt.
I could use compiled libflutter_linux_glfw.so by using --local-engine-src-path and --local-engine options of flutter given in the following link.
Using a locally-built engine with the flutter tool

How to get .apk and .ipa file from flutter?

I am new to flutter programming and I've created a demo app, its running fine on both android and iOS devices. I want to see .apk and .ipa file in flutter. Can anyone help me to get these files from Flutter? Where can I see these files in folders or is there any other solution.
For apk (Android) you need to run the command :
flutter build apk --release
If you want to split the apks per abi (Split Apk) then run
flutter build apk --target-platform android-arm,android-arm64,android-x64 --split-per-abi
For ipa (iOS) you need to run the command :
flutter build ios --release
From the console
P.S. --release is optional as it is by default
if you need debug build, just replace --release with --debug
you can find the released APK or IPA files form
build/app/outputs/flutter-apk/app-release.apk
For Android an APK is generated every time you build the app, e.g. with flutter run. You will find that in your project folder under <project>/build/app/outputs/apk/debug/app-debug.apk. If you want a release APK, have a look at the docs.
I'm not an iOS person, so I'm not sure an IPA is generated during development as in android. But looking at these docs it seems you can follow the standard steps on xcode to get it, as shown here.
For apk (Android) run the command :
flutter build apk --release
For ipa (iOS) run the command :
flutter build ios --release
Then to get actual .ipa file, open xcode -> Product -> archive -> Distribute App -> Ad Hoc -> Export
You can then save the .ipa(which is inside the Runner folder) file in any location
I also had this question and had a really tough time finding the right solution.
First of all in the terminal of your code editor type:
flutter build apk --release
and after that go to this location:
yourAppFolder/build/app/outputs/apk/release/app-release.apk
I do not do development for iOS so I don't know much about that.
For Android, an APK is generated every time you build the app, e.g. with flutter run. You will find that in your project folder under <project>/build/app/outputs/apk/debug/app-debug.apk.
Follow below steps to get .apk and .ipa from flutter app in Mac system
First, Enter below command in your terminal to go your project directory
cd $(PROJECT FOLDER PATH)
For android apk build to upload store, Enter below command
sudo $(FLUTTER SDK PATH till bin)/flutter build apk --release
To get ios ipa , Enter below command
sudo $(FLUTTER SDK PATH till bin)/flutter build ios --release
To get an apk, it is simple. Just use :
flutter build apk
To get an ipa, It is more complicated. First use :
flutter build ipa
Be careful to use flutter build ipa, not flutter build ios, because the second one builds a ".app" file instead of ".xcarchives" file.
Once you have the ".xcarchives" file, you can open it in XCode and click on "Distribute the app" to export an ipa file on your computer.
For iOS:
Step 1: open terminal and type cd "your flutter sdk path"
Step 2: cd export PATH=/Users/yourname/Downloads/flutter/bin:$PATH
Step 3: cd your project path
Step 4: flutter build ios --release
run step 1 to 4 in terminal.
After that open android studio and go to iOS folder path and open project.pbxproj file with ios module and in xcode you need to choose generic ios device and select archive, it will generate ipa build for you.
Android(After adding release build type run below command which will generate release apk with below version)
flutter build apk --build-name=1.0.1 --build-number=1
iOS
flutter build ios --release
For a detail explanation read the below article.
https://medium.com/#ralphbergmann/versioning-with-flutter-299869e68af4
For apk, you can use flutter build apk --release to get the release version of your apk on either windows/macOS.
For ipa, you have to use flutter build ios --release to get the release version of your apk on macOS.
Note: You can get a ipa on macOS only.
If you want this apk and .ipa with flavour then you can refer below commands for internal and production.
iOS:
flutter build ios --debug --flavor internal
flutter build ios --release --flavor production
android:
flutter build apk --debug --flavor internal
flutter build apk --release --flavor production
Updated for iOS :-
first you need to go to your current working directory and run the following command;
flutter build ios --release
After successfully completion of build, you can find build on below path;
/Users/sanjaybalaji/Documents/KiranFlutterApps/hb_calculator/build/ios/iphoneos/Runn
er.app.
you can check below screenshots for more details.
You can find your app apk after you run the app at path
<project_dir>/build/app/outputs/flutter-apk/app.apk

how to build apk create old version app in Flutter

I am trying to build my release app in Flutter and when I run:
flutter run
everything works fine in debugging and test mode. But when I was trying to build a release app with:
flutter build apk
it creates an old first-release app of mine. That I created before and I try to reset the computer reset android and everything but not work what can I do to reset it and clear the cache?
I'm trying almost to delete and reset everything but they don't work.
What command that I have to run to fix it and create new version release apk
The solution is easy.
Just run flutter clean and run flutter build apk after that and it generates the updated app apk.
If you want to install it directly just run flutter install after the build command.
To all the beginners If you wish to release an apk of a flutter app just do:
flutter run --release
(and make sure to connect your device to a phone)
steps to ensure your phone is connected:
1. enable usb debugging mode in your phone
2.click on version number of your phone in system settings to enter into developer mode
3. change the phone mode to transferring file mode
After you run the command
go to build->apps->output->apk
run these command
flutter clean
and after that
flutter build apk --release
Run this command for making a bundle.
flutter build appbundle --target-platform android-arm,android-arm64,android-x64
If flutter clean and flutter build apk also generates apk with old version code in your pubspec.yaml change the version like this version: 1.0.2+2
Before + it is your version name and after + sign it is your version code
NOTE: Your new version number should be in the place of 2. Or you can use different format such as 1.2+2
You can run flutter clean Then run flutter build apk --split-per-abi to split the apk. It will build three apks and you can find them in build/app/outputs/flutter-apk/
Can be done easily by Android Studio