Flutterでstaging/production環境を切替える

 Flutterでstaging/production環境を切替える

Flutter Meetup Tokyo #1 のLT資料です

42edfcc3d726db5b054aeb5aeaf36630?s=128

FURUKI Eiji

April 18, 2018
Tweet

Transcript

  1. 2.

    ࣗݾ঺հ • @fullfool / FURUKI Eiji • iOS / Android

    ΤϯδχΞ • ϞΠגࣜձࣾ • Flutterྺɹࡢ೥8݄த०͔Β • ࠷ۙFlutter৮ͬͯͳ͍
  2. 3.
  3. 8.

    FlavorΛࢦఆͯ͠ΞϓϦΛ࣮ߦ $ flutter run --flavor staging $ flutter run --flavor

    production `--flavor` ΦϓγϣϯͰFlavorΛࢦఆ͢Δ flavorʹࢦఆ͢Δ஋͸Platformଆ(Android/iOS)ͰઃఆࡁΈͷ஋͕ࢦఆͰ ͖·͢
 ͦΕͧΕͷPlatformͰͷFlavorͷఆٛ͸εϥΠυ຤ඌʹ
  4. 10.

    DartͰFlavorΛऔಘ void main() { const String flavor = const String.fromEnvironment('flavor');

    configure(flavor); runApp(new MyApp()); } const bool isReleaseMode = const bool.fromEnvironment('dart.vm.product'); ىಈ࣌ʹFlavorΛऔಘ͍ͨ͠ releaseϞʔυΛऔಘ͢Δ࣌
  5. 11.

    DartͰFlavorΛऔಘ void main() { const String flavor = const String.fromEnvironment('flavor');

    configure(flavor); runApp(new MyApp()); } const bool isReleaseMode = const bool.fromEnvironment('dart.vm.product'); ىಈ࣌ʹFlavorΛऔಘ͍ͨ͠ releaseϞʔυΛऔಘ͢Δ࣌
  6. 14.

    MethodChannelͷొ࿥(Android) new MethodChannel(getFlutterView(), "flavor") .setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void

    onMethodCall(MethodCall methodCall, MethodChannel.Result result) { result.success(BuildConfig.FLAVOR); } }); ΞϓϦىಈ࣌ʹMethodChannelΛొ࿥͢Δ ʢ͜ͷchannel͸Flavorऔಘઐ༻ͷͨΊMethodCall͸ࢀর͠ͳ͍ʣ
  7. 15.

    MethodChannelͷొ࿥(Android) new MethodChannel(getFlutterView(), "flavor") .setMethodCallHandler(new MethodChannel.MethodCallHandler() { @Override public void

    onMethodCall(MethodCall methodCall, MethodChannel.Result result) { result.success(BuildConfig.FLAVOR); } }); ProductFlavor(BuildConfig.FLAVOR)Λฦ͢
  8. 16.

    MethodChannelͷొ࿥(iOS) FlutterViewController* controller = (FlutterViewController*)self.window.rootViewController; FlutterMethodChannel* flavorChannel = [FlutterMethodChannel methodChannelWithName:@"flavor"

    binaryMessenger:controller]; [flavorChannel setMethodCallHandler:^(FlutterMethodCall *call, FlutterResult result) { NSString* flavor = (NSString*)[[NSBundle mainBundle] .infoDictionary valueForKey:@"Flavor"]; result(flavor); }]; Bundleʹఆٛ͢ΔSchemeʹؔ࿈෇͚ͨFlavorΛฦ͢
  9. 17.

    MethodChannelͰFlavorऔಘ void main() { _run(); } Future _run() async {

    var flavor = await MethodChannel('flavor').invokeMethod('getFlavor'); configure(flavor); runApp(new MyApp()); } main.dartͰFlavorΛऔಘͯ͠ɺઃఆΛॳظԽ
  10. 19.

    FlavorຖͷEntry-Point • main.dart͸ "production"ͰઃఆॳظԽ void main() { configure("staging"); runApp(new MyApp());

    } void main() { configure("production"); runApp(new MyApp()); } • main_staging.dart͸ "staging"ͰઃఆॳظԽ
  11. 24.
  12. 26.
  13. 29.

    PlatformͰͷFlavorఆٛ(Android) android { ... defaultConfig {...} buildTypes {...} flavorDimensions "api"

    productFlavors { staging { dimension "api" applicationIdSuffix ".staging" manifestPlaceholders = [appName: "Casmo dev"] } production { dimension "api" manifestPlaceholders = [appName: "Casmo"] } } } ௨ৗͷAndroidΞϓϦͷProductFlavorsͱಉ༷
  14. 38.

    Firebaseͷ੾ସ(iOS) GoogleService-Info-$flavor.plist Λىಈ࣌ʹಡ Έସ͑Δ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    NSString *flavor = (NSString*)[[NSBundle mainBundle] .infoDictionary valueForKey:@"Flavor"]; NSString *firebaseInfo = [NSString stringWithFormat: @"GoogleService-Info-%@", flavor]; NSString *path = [[NSBundle mainBundle] pathForResource:firebaseInfo ofType:@"plist"]; FIROptions* firOptions = [[FIROptions alloc] initWithContentsOfFile:path]; if (firOptions == nil) { assert("Couldn't load config file"); } [FIRApp configureWithOptions:firOptions];
  15. 40.

    Fastlane+Beta(Android) lane :beta do |options| flavor = (options[:prod] ? "production"

    : "staging") entry_dart = (options[:prod] ? "lib/main.dart" : "lib/main_staging.dart") sh("cd ../.. && flutter build apk --flavor #{flavor} -t #{entry_dart} --release && cd -") changelog_from_git_commits # upload to Beta crashlytics( ... ) slack( ... ) end flutter buildͰ؀ڥΛ੾Γସ͑ͯϏϧυ͢Δ
  16. 41.

    Fastlane+Beta(iOS) lane :beta do |options| scheme = (options[:prod] ? "Production"

    : "Staging") flavor = (options[:prod] ? "production" : "staging") entry_dart = (options[:prod] ? "lib/main.dart" : "lib/main_staging.dart") sh("cd ../.. && flutter build ios --flavor #{flavor} -t #{entry_dart} --release && cd -") gym( scheme: scheme, configuration: "Release #{scheme}", export_method: "ad-hoc" ) changelog_from_git_commits # upload to Beta crashlytics( ... ) slack( ... ) end flutter buildͰ؀ڥΛ੾Γସ͑ͯϏϧυ͢Δ