<?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: Trần Thanh Vũ</title>
    <description>The latest articles on DEV Community by Trần Thanh Vũ (@tranthanhvu).</description>
    <link>https://dev.to/tranthanhvu</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%2F517130%2F92942a74-4544-4d43-b8c6-cd6cd881947b.jpeg</url>
      <title>DEV Community: Trần Thanh Vũ</title>
      <link>https://dev.to/tranthanhvu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tranthanhvu"/>
    <language>en</language>
    <item>
      <title>Using Goong Maps in a Flutter project</title>
      <dc:creator>Trần Thanh Vũ</dc:creator>
      <pubDate>Fri, 04 Aug 2023 05:30:33 +0000</pubDate>
      <link>https://dev.to/tranthanhvu/using-goong-maps-in-a-flutter-project-1gnh</link>
      <guid>https://dev.to/tranthanhvu/using-goong-maps-in-a-flutter-project-1gnh</guid>
      <description>&lt;h2&gt;
  
  
  Why didn’t we use Google Maps?
&lt;/h2&gt;

&lt;p&gt;During the process of developing the VNM application, similar to other applications, we used Google maps to display the map. However, due to the Hoang Sa and Truong Sa archipelagos not being displayed on Google Maps, we decided to switch to using Goong Maps, a map developed by a company in Vietnam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compare Google Maps with Goong Maps
&lt;/h2&gt;

&lt;p&gt;To compare Google Maps with Goong Maps, we will make the comparison in the context of building the VNM flutter app. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Common features when using map services such as map, geocoding, routing, distance, and search places are provided by both Google Maps and Goong Map. Goong map API is also designed to be easily switched from Google Map to Goong map with simple endpoint and key changes.&lt;/li&gt;
&lt;li&gt;I believe that GG Map is the best choice for the global market. However, for focusing on the Vietnamese market, using Goong maps may be a different story. Especially, Goong focuses on optimizing data for the Vietnamese market, providing accurate positions even for the outskirts of cities and countrysides, as mentioned in Goong’s documentation.&lt;/li&gt;
&lt;li&gt;The price of using Goong’s services is cheaper. It must be so, otherwise, how can they compete with GG &lt;a href="https://goong.io/bang-gia/"&gt;bang-gia&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Being developed in VN, so they must surely comply with Vietnamese laws and regulations, including accurately displaying the Hoang Sa and Truong Sa archipelagos. &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oXbErIQ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/17gfmn2k2ydizgr9y3a1.png" alt="Map figuration" width="800" height="427"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, choosing to use Goong Map seems so reasonable in case of VNM. The next thing to consider is how easy the implementation is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;Within the scope of the project, I am only concerned about implementing the mobile side, especially using it for the Flutter project.&lt;/p&gt;

&lt;p&gt;As mentioned in Goong’s documentation, we’re going to use MapBox to display Goong Map. In Flutter, we're going to use &lt;a href="https://pub.dev/packages/mapbox_gl"&gt;mapbox_gl&lt;/a&gt; package.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Firstly, you must configure your secret token to download the SDK directly from Mapbox. The guide has been written clearly in the document &lt;a href="https://docs.mapbox.com/ios/maps/guides/install/#configure-credentials"&gt;configure-credentials&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the instruction, for iOS, you have been guided to create the &lt;code&gt;netrc&lt;/code&gt; file at home like the figure below.
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7Y8oHFcC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2pjarcfruy5qfrjjeh9g.png" alt="netrc's path" width="800" height="142"&gt;
&lt;/li&gt;
&lt;li&gt;For Android, you have to create the &lt;code&gt;gradle.properties&lt;/code&gt; similarly.
 &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zo5S6nlZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5a3n4kndil7wj3ss0c50.png" alt="gradle.properties' path" width="800" height="159"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maybe you will be faced with the error regarding arm64 when trying to run it on an iOS simulator. In my case, I just have to set the excluded architectures of pods project to be consistent with arm64 as in the image below:&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--I9GMQhIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8nhc6xlttpz7vmfvq9r7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--I9GMQhIL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8nhc6xlttpz7vmfvq9r7.png" alt="arm64 error" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Because we are using Mapbox to display the Goong map, we must configure the style URL that defines the visual appearance of a map. In my case, it’s Goong style URL &lt;a href="https://docs.goong.io/mobiles/"&gt;docs.goong&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight dart"&gt;&lt;code&gt;    &lt;span class="n"&gt;MapboxMap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nl"&gt;styleString:&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;goongStyleUrl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nl"&gt;onMapCreated:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MapboxMapController&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_mapController&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nl"&gt;initialCameraPosition:&lt;/span&gt; &lt;span class="n"&gt;_kHanoi&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;/li&gt;
&lt;li&gt;

&lt;p&gt;Enjoy your results&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A2TG9p-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrsmi2wakk2u1zejfkm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A2TG9p-x--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lrsmi2wakk2u1zejfkm8.png" alt="Goong map on the iOS simulator" width="300" height="650"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;The use of map services depends on the purpose of projects. From my experience with Goong, it is remarkably easy to use and feels just as familiar as Google Maps. Apart from the initial setup, almost everything works the same. &lt;/p&gt;

&lt;p&gt;Giving it a try if you target the Vietnamese market.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reference links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.goong.io/javascript/"&gt;Goong Documents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://docs.mapbox.com/android/maps/guides/install/"&gt;MapBox Document&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>goong</category>
      <category>mapbox</category>
    </item>
    <item>
      <title>How to download IPA file from AppStore</title>
      <dc:creator>Trần Thanh Vũ</dc:creator>
      <pubDate>Wed, 03 Mar 2021 07:00:01 +0000</pubDate>
      <link>https://dev.to/tranthanhvu/how-to-download-ipa-file-from-appstore-37im</link>
      <guid>https://dev.to/tranthanhvu/how-to-download-ipa-file-from-appstore-37im</guid>
      <description>&lt;p&gt;I still remember the days downloading IPA files from AppStore is very easy through iTunes. But Apple has removed AppStore from iTunes in version 12.7.&lt;/p&gt;

&lt;p&gt;These days, to download IAP files you have to use Apple Configurator 2. It has to do many steps to download an IPA from the App Store, And you can't do it on windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  The steps:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://apps.apple.com/us/app/apple-configurator-2/id1037126344?mt=12" rel="noopener noreferrer"&gt;Apple Configurator 2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Login with the Apple account which used to install the application before&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%2F7zmy7x9gfghcneyoa795.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%2F7zmy7x9gfghcneyoa795.png" alt="Login" width="608" height="58"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Connect your device to MacBook.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the application that you want to download the IPA file.&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%2Fnd5i4zgjh8eu1h2kt0s0.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%2Fnd5i4zgjh8eu1h2kt0s0.png" alt="Add" width="650" height="647"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If it has been installed on your device, the message box will be displayed. Note, Don't select any button on that message box.&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%2Fgi5g4bvj3fc41ojiiflw.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%2Fgi5g4bvj3fc41ojiiflw.png" alt="Don't select any button on that message box." width="650" height="261"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open folder &lt;code&gt;~/Library/Group Containers/K36BKF7T3D.group.com.apple.configurator/Library/Caches/Assets/TemporaryItems/MobileApps/&lt;/code&gt; to find out your IPA file.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's all. &lt;/p&gt;




&lt;h3&gt;
  
  
  P.S
&lt;/h3&gt;

&lt;p&gt;In my case, my client raised an error when they updated the application through AppStore. Then they required me to give them the commercial IPA file to keep track.&lt;/p&gt;

</description>
      <category>appstore</category>
      <category>ipa</category>
    </item>
    <item>
      <title>How to send emails in swiftUI</title>
      <dc:creator>Trần Thanh Vũ</dc:creator>
      <pubDate>Sun, 07 Feb 2021 10:10:34 +0000</pubDate>
      <link>https://dev.to/tranthanhvu/how-to-send-emails-in-swiftui-1ail</link>
      <guid>https://dev.to/tranthanhvu/how-to-send-emails-in-swiftui-1ail</guid>
      <description>&lt;p&gt;Opening an email in an iOS application is a common feature, and I think most applications have it. But sometimes developers' complex mind makes its implementation more complex than it is.&lt;/p&gt;

&lt;p&gt;In the case of swiftUI, the implementation doesn't change, you can use the old code to implement it. In my project, it works perfectly. You can find the full version of the code below.&lt;/p&gt;

&lt;p&gt;Here are some requirements implemented in that file.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create and use an object to help you checking the status of the mail service and handling the MailCompose's delegate.&lt;/p&gt;

&lt;p&gt;I used a static object to able to reuse it in my project.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;
    &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;EmailHelper&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;NSObject&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;/// singleton&lt;/span&gt;
        &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;shared&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;EmailHelper&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="nf"&gt;init&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;p&gt;&lt;span&gt; &lt;/span&gt;&lt;br&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Able to open the external mail or settings app in case users didn't set up any email.&lt;/p&gt;

&lt;p&gt;I just supported the external mails app such as Gmail, Mail. So, if you want to add more, please do it yourself. Note, you have to add Schemes of the app which you want to support.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;
    &lt;span class="c1"&gt;/// Remember to add the below code to Info.plist&lt;/span&gt;
    &lt;span class="c1"&gt;///    &amp;lt;key&amp;gt;LSApplicationQueriesSchemes&amp;lt;/key&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;///    &amp;lt;array&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;///       &amp;lt;string&amp;gt;googlegmail&amp;lt;/string&amp;gt;&lt;/span&gt;
    &lt;span class="c1"&gt;///    &amp;lt;/array&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;&lt;span&gt; &lt;/span&gt;&lt;br&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Related to swiftUI, you don't have to use UIViewRepresentable or UIViewControllerRepresentable here, because you just want to open the mail but don't want to embed it in a View&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;
    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;SettingsView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;Form&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;Section&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SUPPORT"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Help"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="kt"&gt;EmailHelper&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;shared&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Help"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;GlobalConstant&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;App&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;contactEmail&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;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;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;span&gt; &lt;/span&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;





&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>swiftui</category>
      <category>swift</category>
      <category>ios</category>
    </item>
  </channel>
</rss>
