<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Steve</title>
    <description>The latest articles on DEV Community by Steve (@no2s14).</description>
    <link>https://dev.to/no2s14</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F368146%2F2aacc363-cc26-467d-aba6-ff1fd25a47a9.png</url>
      <title>DEV Community: Steve</title>
      <link>https://dev.to/no2s14</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/no2s14"/>
    <language>en</language>
    <item>
      <title>Understanding var, dynamic const, final in Dart</title>
      <dc:creator>Steve</dc:creator>
      <pubDate>Mon, 07 Jun 2021 06:58:45 +0000</pubDate>
      <link>https://dev.to/no2s14/understanding-var-dynamic-const-final-in-dart-1han</link>
      <guid>https://dev.to/no2s14/understanding-var-dynamic-const-final-in-dart-1han</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When you are a beginner with Dart you could get lost in the understanding of the different keywords to create a variable. These variable types in Dart follow a set of rules (some common to other programming languages). This writing aims to provide these rules and to explain to beginners what are the differences between these.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is var ?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt;is a keyword allowing to create a variable without specifying a type. The type of the variable will therefore be determined according to the initial value of this variable.&lt;br&gt;
Note that the type of the variable will be inferred only if you assign it a value at its declaration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"salut"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Will not compile&lt;/span&gt;

  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// runtimeType is int&lt;/span&gt;
  &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"salut"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// runtimeType is String&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens because we are not assigning an initial value to our variable at it's declaration.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is dynamic ?
&lt;/h2&gt;

&lt;p&gt;When creating a variable using the &lt;code&gt;dynamic&lt;/code&gt; keyword, the data type will depend on the variable this variable will contain :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;dynamic&lt;/span&gt; &lt;span class="n"&gt;myVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$myVar&lt;/span&gt;&lt;span class="s"&gt; is of type &lt;/span&gt;&lt;span class="si"&gt;${myVar.runtimeType}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;myVar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Hello World"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$myVar&lt;/span&gt;&lt;span class="s"&gt; is of type &lt;/span&gt;&lt;span class="si"&gt;${myVar.runtimeType}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;2 is of &lt;span class="nb"&gt;type &lt;/span&gt;int
Hello World is of &lt;span class="nb"&gt;type &lt;/span&gt;String
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is final ?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;final&lt;/code&gt; keyword allows you to create variables that can only be assigned once at runtime. This means they are immutable. This keyword is mostly used to create instance variables for a class. &lt;/p&gt;

&lt;h2&gt;
  
  
  What is const ?
&lt;/h2&gt;

&lt;p&gt;You may use the const keyword to create constant values; these variables are implicitly final. The thing you have to take care of is that the value of this variable must be known at compile time :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="n"&gt;myValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;myConst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;myValue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Cannot compile&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;activityCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Will compile&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;myValue's variable is not known at compile time because it's type is infered, therefore Dart will need to determine the type of the variable before executing the code; note that changing myValue to a constant will actually my everything work.&lt;/p&gt;

&lt;p&gt;For a more complete reference, consider reading the &lt;a href="https://dart.dev/guides/language/language-tour"&gt;dart language tour&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for reading, don't hesitate to let me know if you have any suggestion.&lt;/p&gt;

</description>
      <category>dart</category>
    </item>
    <item>
      <title>Add Crashlytics to your WatchOS app</title>
      <dc:creator>Steve</dc:creator>
      <pubDate>Wed, 02 Jun 2021 14:15:31 +0000</pubDate>
      <link>https://dev.to/no2s14/add-crashlytics-to-your-watchos-app-ec7</link>
      <guid>https://dev.to/no2s14/add-crashlytics-to-your-watchos-app-ec7</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I've been working on a WatchKit extension for an existing iOS application recently and i went through a problem: Firebase Crashlytics integration on WatchOS. Since it was quite difficult for me to find a clear documentation about this on the internet i thought it would be interesting to share a step by step guide on how i did it for my project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This guide assumes you already have configured your product in Firebase Console. If it's not the case, you can follow the guide at &lt;a href="https://firebase.google.com/docs/crashlytics/get-started?platform=ios#setup-console" rel="noopener noreferrer"&gt;this url&lt;/a&gt;. Also make sure you have the GoogleService-Info.plist copied at the root of your WatchExtension folder.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Integration
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. Adding the dependency
&lt;/h2&gt;

&lt;p&gt;You'll need to add the dependency to your Podfile as you would on a normal iOS application; make sure to add it under the WatchKit extension target.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;target &lt;span class="s1"&gt;'ExampleApp Watch Extension'&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;platform :watchos, &lt;span class="s1"&gt;'5.1'&lt;/span&gt;
    &lt;span class="c"&gt;# other dependencies&lt;/span&gt;
    pod &lt;span class="s1"&gt;'Firebase/Crashlytics'&lt;/span&gt;, &lt;span class="s1"&gt;'7.10.0'&lt;/span&gt;
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you'll need to run the two command below to update your dependencies and launch your app in XCode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;pod &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;open example-app.xcworkspace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Adding Firebase Crashlytics SDK to your app
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In your &lt;code&gt;ExtensionDelegate.swift&lt;/code&gt; file, import the Firebase module:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Firebase&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Next step is to configure FirebaseApp. It's recommanded to do this in the &lt;a href="https://developer.apple.com/documentation/watchkit/wkextensiondelegate/1628241-applicationdidfinishlaunching" rel="noopener noreferrer"&gt;applicationDidFinishLaunching()&lt;/a&gt; method:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;applicationDidFinishLaunching&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Firebase configuration&lt;/span&gt;
    &lt;span class="kt"&gt;FirebaseApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Compile your app again.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Crashlytics initialisation
&lt;/h2&gt;

&lt;p&gt;You'll need to initialize crashlytics by adding a Build Phase to your project so XCode will automatically download your project's DSYM file each time your application will crash, so that Crashlytics will be able to automatically generate crash reports.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1:&lt;/strong&gt; Open XCode and select the project in the left navigation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2:&lt;/strong&gt; Click on the WatchKit Extension target and go to the Build Phases tab.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3:&lt;/strong&gt; Click the plus button on the top left side, then choose the "New Run Script Phase" option&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 4:&lt;/strong&gt; Add this code
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PODS_ROOT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/FirebaseCrashlytics/run"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should then have something like this :&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lf0b9e7cdp12gqiw16f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9lf0b9e7cdp12gqiw16f.png" alt="SC 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;make sure that your new generation phase is the last generation phase of the project, otherwise Crashlytics cannot initialize correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 5:&lt;/strong&gt; Take some beer, you've just accomplished something great !&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  4. Test your integration
&lt;/h2&gt;

&lt;p&gt;Now we have configured Crashlytics in our project, we need to make sure it works.&lt;br&gt;
To do this, we will create a test crash and see how it's handled by Crashlytics and showed in our console.&lt;/p&gt;

&lt;p&gt;Go to your project settings, choose the Watch target (&lt;strong&gt;i said Watch, not Watch Extension&lt;/strong&gt;); then go the the &lt;code&gt;Build settings&lt;/code&gt; tab and type &lt;code&gt;debug information format&lt;/code&gt; in the search bar. the value is probably 'DWARF', change it to &lt;code&gt;DWARF with dSYM File&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Why this you'll ask me (yeah, i can read your mind ;) )&lt;br&gt;
You actually need to disconnect your simulator from your XCode debugger to be able to see crash reports in the crashlytics console. (don't ask me why, I am not employed at Google, even if I dream of it).&lt;/p&gt;

&lt;p&gt;Go to your app (for example the ExtensionDelegate.swift) file and add the code below after Firebase configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;applicationDidFinishLaunching&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Firebase configuration&lt;/span&gt;
    &lt;span class="kt"&gt;FirebaseApp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kt"&gt;Crashlytics&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;crashlytics&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;record&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Test crash"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mo"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;userInfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you are done, launch your app and you normally should be able to see your first report in your Crashlytics console.&lt;/p&gt;

&lt;p&gt;Thanks for reading, and don't hesitate to leave a comment if you have any suggestion or questions.&lt;/p&gt;

</description>
      <category>watchos</category>
      <category>firebase</category>
      <category>crashlytics</category>
      <category>swift</category>
    </item>
    <item>
      <title>How to use WKCrownDelegate in WatchOS Development</title>
      <dc:creator>Steve</dc:creator>
      <pubDate>Wed, 24 Mar 2021 09:15:28 +0000</pubDate>
      <link>https://dev.to/no2s14/how-to-use-wkcrowndelegate-in-watchos-development-1lj9</link>
      <guid>https://dev.to/no2s14/how-to-use-wkcrowndelegate-in-watchos-development-1lj9</guid>
      <description>&lt;p&gt;Hi everyone.&lt;/p&gt;

&lt;p&gt;While working on a WatchOS application recently I needed to perform some operations in the application when the user rotated the digital crown; I had difficulties to find the solution because there were very few resources on the subject, and the official documentation is not clear enough for me. (A full example is always better).&lt;br&gt;
After doing some research on the subject, I finally was able to find a solution and this guide will explain step by step how I achieved it.&lt;/p&gt;

&lt;p&gt;So i'm using Swift 5 on XCode 12.4 with WatchKit.&lt;/p&gt;

&lt;p&gt;We gonna start from a blank project so it's clear for everybody:&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;InterfaceController&lt;/code&gt;code looks like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;WatchKit&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;InterfaceController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WKInterfaceController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;awake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;withContext&lt;/span&gt; &lt;span class="nv"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Configure interface objects here.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;willActivate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This method is called when watch view controller is about to be visible to user&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;didDeactivate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This method is called when watch view controller is no longer visible&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first step will be to modify our InterfaceController so it conforms to &lt;code&gt;WKCrownDelegate&lt;/code&gt; protocol.&lt;br&gt;
This looks like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;InterfaceController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WKCrownDelegate&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before implementing our protocol methods, we will need to add some code to our &lt;code&gt;InterfaceController&lt;/code&gt; class; we need to tell the crownSequencer it should focus, and define a delete.&lt;br&gt;
To do that, add a &lt;code&gt;didAppear()&lt;/code&gt; method (this method is automatically called when the watch interface is visible to user). This looks like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;didAppear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;didAppear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;crownSequencer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
    &lt;span class="n"&gt;crownSequencer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are ready to listen to events; the available ones are : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;func crownDidRotate(WKCrownSequencer?, rotationalDelta: Double)&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Called when the user rotates the crown.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;func crownDidBecomeIdle(WKCrownSequencer?)&lt;/code&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Called when the user stops rotating the crown.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Full code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;WatchKit&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;InterfaceController&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WKInterfaceController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;awake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;withContext&lt;/span&gt; &lt;span class="nv"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Configure interface objects here.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;willActivate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This method is called when watch view controller is about to be visible to user&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;didAppear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;didAppear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;crownSequencer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delegate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;
        &lt;span class="n"&gt;crownSequencer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;focus&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;didDeactivate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// This method is called when watch view controller is no longer visible&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;InterfaceController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WKCrownDelegate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;crownDidRotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;crownSequencer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;WKCrownSequencer&lt;/span&gt;&lt;span class="p"&gt;?,&lt;/span&gt; &lt;span class="nv"&gt;rotationalDelta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Double&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rotationalDelta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the digital crown will rotate, the rotational delta will be printed like on the screenshot below :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5owoks2daeuzaquft63y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5owoks2daeuzaquft63y.png" alt="Capture d’écran 2021-03-24 à 10.11.51"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope this article has helped you, feel free to add your suggestions in comments.&lt;/p&gt;

&lt;p&gt;Have a nice day! (or night)&lt;/p&gt;

</description>
      <category>swift</category>
      <category>watchos</category>
      <category>watchkit</category>
    </item>
    <item>
      <title>Hide your api keys from your android manifest file with Flutter using local.properties</title>
      <dc:creator>Steve</dc:creator>
      <pubDate>Wed, 26 Aug 2020 12:06:03 +0000</pubDate>
      <link>https://dev.to/no2s14/hide-your-api-keys-from-your-android-manifest-file-with-flutter-using-local-properties-3f4e</link>
      <guid>https://dev.to/no2s14/hide-your-api-keys-from-your-android-manifest-file-with-flutter-using-local-properties-3f4e</guid>
      <description>&lt;p&gt;A common problem we face is the protection of out private data such as API keys.&lt;br&gt;
When working with Flutter, you may need to integrate a third party service which requires you to add your API key to your manifest file.&lt;/p&gt;

&lt;p&gt;You wouldn't want to check-in your API keys to the source code. Instead, you would like to embed them into an internal file ignored by your source control and use  them through your app. For Android there's already a standard file that's used for this purpose called local.properties.&lt;/p&gt;

&lt;p&gt;The AndroidManifest.xml is an xml file thus  we cannot write scripts there. Instead, we can write a small script in build.gradle file, read api key from the local.properties file and assign it to a variable. AndroidManifest will be able to read that variable.&lt;/p&gt;

&lt;p&gt;Let's dive into the code!&lt;/p&gt;

&lt;p&gt;Assuming we want to integrate segment, we would need to add the write key toe our AndroidManifest.xml file, instead of writing the clear API key, we would write :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"com.claimsforce.segment.WRITE_KEY"&lt;/span&gt; &lt;span class="na"&gt;android:value=&lt;/span&gt;&lt;span class="s"&gt;"${segmentWriteKey}"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then register the API Key in the &lt;code&gt;local.properties&lt;/code&gt; file under the variable named "segment.writeKey" like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;sdk&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="n"&gt;flutter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;sdk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;
&lt;span class="n"&gt;flutter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;buildMode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;debug&lt;/span&gt;
&lt;span class="n"&gt;flutter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;versionName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;flutter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;versionCode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;segment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;writeKey&lt;/span&gt;&lt;span class="o"&gt;=&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;SEGMENT&lt;/span&gt; &lt;span class="n"&gt;API&lt;/span&gt; &lt;span class="n"&gt;KEY&lt;/span&gt; &lt;span class="n"&gt;GOES&lt;/span&gt; &lt;span class="n"&gt;HERE&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="n"&gt;We&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;ve&lt;/span&gt; &lt;span class="n"&gt;added&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;segmentWriteKey&lt;/code&gt; is the name of the variable we are going to create in the module level build.gradle (android/app/build.gradle).&lt;/p&gt;

&lt;p&gt;Add these lines before android{}  :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'local.properties'&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;newDataInputStream&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;segmentWriteKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'segment.writeKey'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Notice we get the property we the exact same name we wrote in the local.properties file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should look like :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'local.properties'&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;newDataInputStream&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; 
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;segmentWriteKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'segment.writeKey'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;compileSdkVersion&lt;/span&gt; &lt;span class="mi"&gt;28&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the android section, in the defaultConfig, add this line to the end:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;manifestPlaceholders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nl"&gt;segmentWriteKey:&lt;/span&gt; &lt;span class="n"&gt;segmentWriteKey&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now everything should look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;Properties&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Properties&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;load&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;rootProject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'local.properties'&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;newDataInputStream&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt;
&lt;span class="kt"&gt;def&lt;/span&gt; &lt;span class="n"&gt;segmentWriteKey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;properties&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getProperty&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'segment.writeKey'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;defaultConfig&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="n"&gt;manifestPlaceholders&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nl"&gt;segmentWriteKey:&lt;/span&gt; &lt;span class="n"&gt;segmentWriteKey&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that the local.properties file is ignore by the source control by default so you will not have to do it yourself (but prevention is better than cure ;) ).&lt;/p&gt;

&lt;p&gt;Well, we are done.&lt;br&gt;
Hope this article helped you and see you on another one.&lt;br&gt;
Thanks for reading.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>android</category>
      <category>security</category>
    </item>
    <item>
      <title>Flutter app development good practices</title>
      <dc:creator>Steve</dc:creator>
      <pubDate>Thu, 16 Apr 2020 17:46:54 +0000</pubDate>
      <link>https://dev.to/no2s14/flutter-app-development-good-practices-9m5</link>
      <guid>https://dev.to/no2s14/flutter-app-development-good-practices-9m5</guid>
      <description>&lt;p&gt;Hello everyone,&lt;/p&gt;

&lt;p&gt;Please be lenient on the quality of the writing as this is my first article. Nevertheless I would make efforts to improve myself in my next essays.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This article may include elements mentioned on the documentation at &lt;a href="https://flutter.dev/docs/perf/rendering/best-practices"&gt;https://flutter.dev/docs/perf/rendering/best-practices&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The content you will read in this article is based on my own experience and may be very opinionated.&lt;/p&gt;

&lt;h2&gt;
  
  
  The guidelines
&lt;/h2&gt;

&lt;p&gt;I know, it can be a pain in the ass to do so much reading, but you'll thank me later.&lt;br&gt;
Before you start developing mobile applications (with Flutter, or any other technology), please read the guidelines.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/design"&gt;Android guidelines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/design/human-interface-guidelines/"&gt;iOS guidelines&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;They'll give you strong knowledge about platform specific design patterns to improve your users experience.&lt;/p&gt;
&lt;h2&gt;
  
  
  Don’t make costly operations in your build methods
&lt;/h2&gt;

&lt;p&gt;Do nothing else than building your UI in your build method; adding costly operations (like async calls or too big calculations) can lead to performance losses or unwanted behaviors (yeah, Flutter is very fast, but let's not abuse it  😉)&lt;/p&gt;
&lt;h2&gt;
  
  
  Avoid large trees, split your code into small widgets instead
&lt;/h2&gt;

&lt;p&gt;Dividing your code into small reusable widgets not only promotes its reusability, but also its readability. So, you should split your code into different Widgets based not only on encapsulation but also on how “it changes”&lt;/p&gt;
&lt;h2&gt;
  
  
  Use widgets instead of _buildXXX (methods) to build UI elements
&lt;/h2&gt;

&lt;p&gt;Build widgets instead of builder methods. Using methods instead of classes to build UI elements can not only lead to performance losses, but also to unwanted behaviors or silly-nilly bugs.&lt;/p&gt;
&lt;h2&gt;
  
  
  Use absolute positioning only when it’s truely necessary
&lt;/h2&gt;

&lt;p&gt;Responsiveness/adaptability  is a well-known topic today. Not all devices have the same pixel density, nor the same size, etc... so it's important to build UIs that adapt to all theses changes. I personally use absolute values for some cases (paddings, margins, border radiuses, etc...)&lt;/p&gt;
&lt;h2&gt;
  
  
  Flex is life
&lt;/h2&gt;

&lt;p&gt;Prefer using Flex widgets as much as you can. The ones that come to my mind are (&lt;code&gt;Row&lt;/code&gt;, &lt;code&gt;Column&lt;/code&gt;, &lt;code&gt;Flex&lt;/code&gt;, &lt;code&gt;Expanded&lt;/code&gt;, &lt;code&gt;Flexible&lt;/code&gt;). You can find further explanations &lt;a href="https://medium.com/flutterdevs/expanded-and-flexible-in-flutter-68f58c7f3ce0"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  "const", my friend
&lt;/h2&gt;

&lt;p&gt;Use const constructors whenever possible when building your own widgets or using Flutter widgets. This helps Flutter to rebuild only widgets that should be updated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;Widget&lt;/span&gt; &lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BuildContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Column&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="nl"&gt;children:&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;
          &lt;span class="n"&gt;AspectRatio&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;aspectRatio:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello world"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;],&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Widgets choice matters
&lt;/h2&gt;

&lt;p&gt;It is important to choose the widgets to use when you want to build a view. A bad choice of widgets can lead to a too large tree and a lot of useless code. &lt;br&gt;
Always remember to check if a native widget does not exist before creating yours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use packages only when necessary
&lt;/h2&gt;

&lt;p&gt;Packages can be a good choice when you want to speed up your building process and &lt;a href="https://pub.dev"&gt;pub&lt;/a&gt; has a ton of them. Nonetheless, they can have significant effects on your app performances when they are used without prior study&lt;/p&gt;

&lt;h2&gt;
  
  
  Dealing with lists
&lt;/h2&gt;

&lt;p&gt;Use the default constructor &lt;code&gt;ListView&lt;/code&gt; for rendering small lists of known size; for longer lists (for example a list returned by the API call), use the &lt;code&gt;ListView.builder&lt;/code&gt; constructor which renders list elements as users scroll to them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important notice:&lt;/strong&gt; The shrinkWrap attribute on a ListView will force it to calculate it's size and thus to render all the elements at once.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Linting
&lt;/h2&gt;

&lt;p&gt;Dart is great and we love it. It offers us a lot of freedom, but sometimes too much, so it is important to limit its features to prevent bugs in the application later.&lt;br&gt;
One of your first reflexes when creating a new Flutter project should be to create the &lt;code&gt;analysis_options.yml&lt;/code&gt; file at the root of your project.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;[UPDATE: 11/04/2022]&lt;/em&gt;&lt;br&gt;
When you create a project with the latest versions of Flutter, the analysis_options.yml file is now created by default with the official lint rules&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Visit &lt;a href="https://flutter.dev/docs/perf/rendering/best-practices"&gt;https://flutter.dev/docs/perf/rendering/best-practices&lt;/a&gt; for a complete reference about the two first points, and more other good practices.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thank you for reading.&lt;br&gt;
Leave a comment if you have any suggestion, or if you don’t agree on some points.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
    </item>
  </channel>
</rss>
