<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Posts on Eduardo Almeida</title>
        <link>/posts/</link>
        <description>Recent content in Posts on Eduardo Almeida</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-us</language>
        <copyright>Eduardo Almeida</copyright>
        <lastBuildDate>Thu, 24 Sep 2020 19:00:00 +0000</lastBuildDate>
        <atom:link href="/posts/index.xml" rel="self" type="application/rss+xml" />
        
        <item>
            <title>Navigation on a timepiece</title>
            <link>/posts/2020/09/navigation-on-a-timepiece/</link>
            <pubDate>Thu, 24 Sep 2020 19:00:00 +0000</pubDate>
            
            <guid>/posts/2020/09/navigation-on-a-timepiece/</guid>
            <description>This is just a quick blog post about my recent experiences with SwiftUI 2, the new version of SwiftUI for iOS 14 and related operating systems. This is going to be both small and highly technical, so I apologize in advance.
While making a simple app for watchOS (the timepiece of this post!), I noticed that the chevron to go back between views (the navigation!) would never appear.
For comparision, this is the expected result in an app like Settings:</description>
            <content type="html"><![CDATA[<p>This is just a quick blog post about my recent experiences with SwiftUI 2, the new version of SwiftUI for iOS 14 and related operating systems. This is going to be both small and highly technical, so I apologize in advance.</p>

<p>While making a simple app for watchOS (the timepiece of this post!), I noticed that the chevron to go back between views (the navigation!) would never appear.</p>

<p align="middle">
  <img style="display: inline-block;" src="/images/navigation-timepiece-bug-1.png" width="35%" /> <img style="display: inline-block;" src="/images/navigation-timepiece-bug-2.png" width="35%" /> 
</p>

<p>For comparision, this is the expected result in an app like Settings:</p>

<p align="middle">
  <img style="display: inline-block;" src="/images/navigation-timepiece-settings-1.png" width="35%" /> <img style="display: inline-block;" src="/images/navigation-timepiece-settings-2.png" width="35%" /> 
</p>

<p>As it turns out&hellip; if you embed a <code>NavigationView</code> inside another <code>NavigationView</code>, that chevron will never appear. A <code>NavigationView</code> is automatically created for you when you create a new watchOS app, so that&rsquo;s something to keep in mind. Removing the outer <code>NavigationView</code> will fix the issue.</p>

<p align="middle">
  <img style="display: inline-block;" src="/images/navigation-timepiece-fixed-1.png" width="35%" /> <img style="display: inline-block;" src="/images/navigation-timepiece-fixed-2.png" width="35%" /> 
</p>

<p>Aaand, that&rsquo;s everything. Just a quick note so no one else has to waste an Apple technical request like I did!</p>

<p>Oh, I almost forgot: Make sure to check out&nbsp;<a href="https://github.com/edualm/SeedTruck">SeedTruck</a>, the open-source SwiftUI 2 project where I had this problem. It&rsquo;s a project with a single code base that works on iOS, macOS, tvOS and watchOS!</p>
]]></content>
        </item>
        
        <item>
            <title>Does native still matter?</title>
            <link>/posts/2020/04/does-native-still-matter/</link>
            <pubDate>Thu, 09 Apr 2020 00:00:00 +0000</pubDate>
            
            <guid>/posts/2020/04/does-native-still-matter/</guid>
            <description>Ever since the SDKs for iOS and Android applications were launched, alternative ways of developing for these platforms appeared. In the beginning, these were frameworks like PhoneGap and Cordova, which allowed users to develop using HTML/JS, but then other frameworks like Xamarin.Forms, React Native and, more recently, Flutter (which uses its own language, Dart) surfaced.
One could argue that the first frameworks weren&amp;rsquo;t that good - effectively, you were only rendering web pages and your apps were nothing more than glorified web views with maybe a bit more system access than your average web browser, and they wouldn&amp;rsquo;t feel native.</description>
            <content type="html"><![CDATA[

<p><center>
<img src="/images/programming-mobile.png" alt="Header Image" />
</center></p>

<p>Ever since the SDKs for iOS and Android applications were launched, alternative ways of developing for these platforms appeared. In the beginning, these were frameworks like PhoneGap and Cordova, which allowed users to develop using HTML/JS, but then other frameworks like Xamarin.Forms, React Native and, more recently, Flutter (which uses its own language, Dart) surfaced.</p>

<p>One could argue that the first frameworks weren&rsquo;t that good - effectively, you were only rendering web pages and your apps were nothing more than glorified web views with maybe a bit more system access than your average web browser, and they wouldn&rsquo;t feel native.</p>

<p>React Native and Flutter are on a different league: they both use the system APIs to draw things on screen, as opposed to being just a web view. React Native runs on top of a JavaScript engine, while Flutter can compile directly to native code, which theoretically means that apps built with Flutter may be able to squeeze more performance. React Native should still be fast enough, though. Xamarin.Forms is also a contender in this space, but it&rsquo;s not as widely used, so for the scope of this post, I am going to focus on React Native and Flutter as the &ldquo;current&rdquo; cross-platform frameworks.</p>

<hr />

<p>They aren&rsquo;t the holy-grail of mobile development though. There are some pain points, which you need to consider when you want to develop an app.</p>

<h3 id="single-threading">Single-Threading</h3>

<p>They are based on single-threaded languages. This is all good and dandy, except when you start thinking about the fact that Android phones usually have a lot of cores which don&rsquo;t usually run at especially high clock speeds - the same doesn&rsquo;t really apply for iOS devices, but you need to think about both, else why would you think about using a cross-platform framework in the first place… Why is this a problem, though? Well, a single thread is usually enough for simple apps, but for apps that try to do stuff in the background, like cache data for future usage or run complex computations while the user is doing something else, it can be problematic, as performance of both the main and background task will suffer.</p>

<p>To be fair, this doesn&rsquo;t apply to Xamarin.Forms, but that one comes with its share of problems that are outside the scope of this post.</p>

<h3 id="ui-consistency">UI Consistency</h3>

<p>It&rsquo;s true that you can have a single app that easily looks the same on both iOS and Android, even more if you use Flutter due to its game engine nature, but is that something you really want? Users expect a user interface consistent to the UI guidelines of their framework, not something that just looks good. Also, there are things that are different between platforms - you don&rsquo;t have a dedicated back button on iOS, for example, and your UI needs to change and reflect that. You&rsquo;re going to have a hard time dealing with designers if they expect the design to be &ldquo;write once, run anywhere&rdquo;.</p>

<h3 id="library-ecosystem">Library Ecosystem</h3>

<p>Library ecosystem also isn&rsquo;t great. Flutter and React Native are always changing, and libraries need to be upgraded to reflect that. It&rsquo;s quite possible you want to use a library that was built a few months ago and wasn&rsquo;t maintained since then (which isn&rsquo;t really that much time), but you can&rsquo;t since it doesn&rsquo;t support the version of the framework you&rsquo;re using, something that doesn&rsquo;t really happen if you are building a native app. Also, you are going to need to upgrade your framework from time to time, which can take days of work for a developer even for a small app since there are small but breaking changes on new framework releases.</p>

<h3 id="os-specific-features">OS-Specific Features</h3>

<p>You also need to think about the features your app will use. You can do things like widgets and get low-level hardware access on apps built on top of cross-platform frameworks, but you&rsquo;ll need to dive into native code, write code for all the platforms you are targeting, and write a bridge on top of that so it can be used from your cross-platform code. If you need to use features that are only available on a platform or are not supported by the framework of your choice, you&rsquo;re going to spend a lot more time than if you went native in the first place. A notable example is that you can&rsquo;t currently develop apps for watchOS using a cross-platform framework, and support for Wear OS is also quite limited - you need to dive deep into native code and even create entirely separate apps in both cases.</p>

<h3 id="developers">Developers</h3>

<p>Another argument is that it is easier to hire cross-platform developers than native ones, since you can just hire people that know JavaScript (in the case of React Native) and be done with it. That&rsquo;s, unfortunately, not true. You will undoubtedly run into issues while building your app, and will need to fix issues that are specific to a single OS, which requires the developer to have at least intermediate-level knowledge of the platforms they are targeting. In addition, you&rsquo;ll most likely run into some weird issues that would never happen on native apps. So, instead of needing an iOS developer, you now need a JavaScript developer that knows how to dabble in both iOS and Android. Is it that better?</p>

<hr />

<p>Most of my points have been focused on performance and features. This is something that you may not really care that much about if you are building a prototype or a simple app. There are, of course, positive arguments to be made for each one of native and cross-platform.</p>

<p>There&rsquo;s no doubt that the time to market of a single cross-platform app, one that is simple and doesn&rsquo;t need to do much out of the ordinary (like access to specific hardware or functionality only available on a single OS), will be much smaller on a cross-platform app than when building two different apps.</p>

<p>Prototyping time is also usually faster in Flutter and React Native when compared to native languages, since you can use features like Hot Reload which allow you to see changes you make to the UI on your code in real-time. This is not so much of an issue with newer technologies like SwiftUI on the iOS side of things, but we&rsquo;re still not quite there yet.</p>

<p>Additionally, the performance penalty may not be that noticeable if your app doesn&rsquo;t do much more than display data or allow the user to interact with data in a simple way.</p>

<p>There are examples of apps that started out as not much more than being glorified web views then moved on to full-blown apps - the Facebook app being a good example of this - so that&rsquo;s also a possibility if your use case allows.</p>

<hr />

<p>In conclusion… if you need something out in the market in the lesser time possible, for both iOS and Android at the same time, cross-platform frameworks may be a good choice. But if you want instead a small, performant, capable app you can rely on… </p>

<p><strong>Go native!</strong></p>

<hr />

<p><strong>This article was updated on April 22nd to fix some minor grammar issues.</strong></p>
]]></content>
        </item>
        
        <item>
            <title>Go-ing Serverless</title>
            <link>/posts/2019/09/go-ing-serverless/</link>
            <pubDate>Thu, 05 Sep 2019 20:00:00 +0100</pubDate>
            
            <guid>/posts/2019/09/go-ing-serverless/</guid>
            <description>Some articles will tell you about the best way to do something. This is not one of those. This is an article about experimenting, making bad decisions, and getting the best out of a bad situation.
SongButler is one of After Hours Solutions’ apps — actually, at the time of writing, the only app (if you haven’t tried it out, now is a good time to do that at https://songbutler.app). Let me start by telling you right now that both the landing page and app is costing us $0.</description>
            <content type="html"><![CDATA[<p>Some articles will tell you about the best way to do something. This is not one of those. This is an article about experimenting, making bad decisions, and getting the best out of a bad situation.</p>

<p>SongButler is one of After Hours Solutions’ apps — actually, at the time of writing, the only app (if you haven’t tried it out, now is a good time to do that at <a href="https://songbutler.app">https://songbutler.app</a>). Let me start by telling you right now that both the landing page and app is costing us $0.00 to keep alive. But that wasn’t the original idea.</p>

<p>When I first started this project, I had a goal in mind: learn Go. And so I did. But by restricting my goal to that, we didn’t think much about deployment — we figured we’d just deploy it in a cheap virtual server and call it a day. Rookie mistake, eh? So, the project was finished in about a week, and we had a big ol’ Go binary, using almost no external libraries and the default net/http package serving all requests. I was happy about it! But then I had to deploy it, and that’s when the (late) idea of serverless surfaced.</p>

<p>It can’t be so hard, right?</p>

<p><center>
<img src="/images/you-must-be-new-here.gif" alt="You must be new here GIF" />
</center></p>

<hr />

<p>Serverless, even if an afterthought, should be easy (well, that’s what I thought). I just need to deploy this binary as an AWS Lambda or something and have a good night of sleep. (Nope.)</p>

<p>First of all, you don’t have the concept of a web server running and accepting requests, so scrape everything you think you know about HTTP request handling and whatsoever. Serverless consists of a function (or a series of functions in a project) that takes an input and outputs something (normally, at least). Oh, and, yeah, of course that function runs in a server, so great job with the name serverless, whoever thought about it. It’s more like manageless, since the only difference is that you don’t need to actually manage a server. But having said that, how in the world am I supposed to handle requests, you ask? Well… something does that for you.</p>

<p>Being a serverless novice, I went with what everyone uses (and is more Googleable…) — Amazon Web Services, or AWS, as everyone calls it. A serverless function is called a lambda function in the AWS world, and there’s really not much more to it. And a lambda function can be ran in response to a signal from something, and that something can be a gateway that basically routes HTTP requests. Perfect.</p>

<p>Kind of.</p>

<p>I already had a perfectly good app, with routing built-in. That doesn’t really fit the serverless model. Fortunately, I found a nice little library that could be used as a drop-in replacement for go’s net/http library.</p>

<p>Here is the app’s entry point before:</p>

<pre><code>func main() {
	cfg := cmd.Init()

	http.HandleFunc(&quot;/slack/help&quot;, web.SlackSlashHelpHandler)
	(...)
	http.HandleFunc(&quot;/slack/webhook&quot;, web.SlackEventHandler)

	if err := http.ListenAndServe(fmt.Sprintf(&quot;:%d&quot;, cfg.Port), nil); err != nil {
		panic(err)
	}
}
</code></pre>

<p>And here’s the after:</p>

<pre><code>func main() {
	cmd.Init()

	http.HandleFunc(&quot;/slack/help&quot;, web.SlackSlashHelpHandler)
	(...)
	http.HandleFunc(&quot;/slack/webhook&quot;, web.SlackEventHandler)

	gateway.ListenAndServe(&quot;&quot;, nil)
}
</code></pre>

<p>Not too different, right? And… it basically works. The issue is that we still have a single binary serving everything. It’s serverless, sure, but I wanted each endpoint to be divided into a separate binary. I guess I should have thought about that earlier though, eh? You can’t have everything going your way unless you plan things accordingly.</p>

<p>Of course, I also ran into some problems — for example, debugging code when it isn’t running in a machine you control is a pain — but Go turned out to be the right tool for the job, along with serverless.</p>

<p><center>
<img src="/images/jim-carrey-programming.gif" alt="Jim Carrey Programming" />
</center></p>

<hr />

<p>There is some stuff that I haven’t talked about in this post (like how to group everything in AWS, the creation of an API gateway, etc.) but that’s a bit out of scope. The giveaway here is that serverless is, in my opinion, a nice choice for apps that don’t do a lot of work and don’t need to be actually running (processing stuff) all the time, only at regular intervals or in response to an event. Pair that with the generous free tier of AWS, and you have got yourself free, reliable (most of the time) hosting!</p>
]]></content>
        </item>
        
        <item>
            <title>Hello World</title>
            <link>/posts/2019/05/hello-world/</link>
            <pubDate>Sun, 19 May 2019 19:47:37 +0100</pubDate>
            
            <guid>/posts/2019/05/hello-world/</guid>
            <description>Hey! 👋
I see that you&amp;rsquo;re exploring my website, but probably there&amp;rsquo;s not much to see right now.
I may share programming-related stuff here from time to time.</description>
            <content type="html"><![CDATA[<p>Hey! 👋</p>

<p>I see that you&rsquo;re exploring my website, but probably there&rsquo;s not much to see right now.</p>

<p>I may share programming-related stuff here from time to time.</p>
]]></content>
        </item>
        
    </channel>
</rss>
