<?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: Pablo Terradillos</title>
    <description>The latest articles on DEV Community by Pablo Terradillos (@tehsis).</description>
    <link>https://dev.to/tehsis</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%2F323630%2F1a3d1385-7db4-4521-9973-94a2db0cce4c.jpeg</url>
      <title>DEV Community: Pablo Terradillos</title>
      <link>https://dev.to/tehsis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tehsis"/>
    <language>en</language>
    <item>
      <title>Designing enemies</title>
      <dc:creator>Pablo Terradillos</dc:creator>
      <pubDate>Thu, 08 Feb 2024 11:35:00 +0000</pubDate>
      <link>https://dev.to/tehsis/designing-enemies-3e77</link>
      <guid>https://dev.to/tehsis/designing-enemies-3e77</guid>
      <description>&lt;p&gt;In this article, I'm going to share my thinking / design process for the human enemies on the game I'm working on (Vectoria) &lt;/p&gt;

&lt;p&gt;I probably need to make another post telling a bit more about the game. For now, you just need to know it is a platformer ambiented on a space cruiser where the main characters uses a jetpack and have a laser gun.&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%2Fek7atci15j40ptmuyjly.jpeg" 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%2Fek7atci15j40ptmuyjly.jpeg" alt="An IA generated cover for the game"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The prototype
&lt;/h2&gt;

&lt;p&gt;To start with, I wanted to be able to have something to test on as quickly as possible. So for &lt;a href="https://tehsis.itch.io/vectoria" rel="noopener noreferrer"&gt;the prototype&lt;/a&gt;, I just copied most of the main character asset and made the enemy start to shoot as soon as it approaches (ie. enters a collision area)&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%2Fs7snu8pnhnpha343knts.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%2Fs7snu8pnhnpha343knts.png" alt="A prototype representation of the main character and the enemy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was… not very good. The player could just fly and avoid the battle all together.&lt;br&gt;
So I made the enemy a bit smarter: it jumps if detects that the player is not on the floor. Now the battle was not avoidable.&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%2F0s4ou8zhmkki6457lh6g.jpeg" 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%2F0s4ou8zhmkki6457lh6g.jpeg" alt="Sketch of the enemy jump when player flies"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That was it for the prototype really. The simple “AI”[1] allowed me to test it with some friends and see how they react: On most of my tests, they found the battle engaging enough. Although it's worth mentioning none of them replayed the game.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now on the real game
&lt;/h2&gt;

&lt;p&gt;Out of the prototype, I already knew I wanted my enemies to be smarter and keep iterating on how they behave. So while I would just mimic the same behavior as for the prototype to start with, I made it more modular and simpler to extend and modify utilizing a &lt;a href="https://gameprogrammingpatterns.com/state.html" rel="noopener noreferrer"&gt;Finite State Machine (FSM)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first state (Which I called &lt;em&gt;Idle&lt;/em&gt;) was simple: the enemy won´t do anything, just wait for the player to appear.&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%2F4bq5ovafakovnjwajqg0.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%2F4bq5ovafakovnjwajqg0.png" alt="A Finite state machine with a single "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the player approaches the enemy, it will start to shoot every fixed amount of time. This was the “Attack”  State.&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%2F1koa5qja4nz5rarclsen.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%2F1koa5qja4nz5rarclsen.png" alt="An FSM with an Idle state that transition to attack if the player approaches"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And, of course, if the player tries to flight over the enemy, it will jump and get back to Attack.&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%2Fb6z1e960djomub4vllpw.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%2Fb6z1e960djomub4vllpw.png" alt="A new state "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good, I was back to the prototype state, but now with a simpler way to extend the enemy “cleverness” (The source code for the prototype was a real spaghetti).&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%2Fh98ipnjm7m65v31ljhnp.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%2Fh98ipnjm7m65v31ljhnp.png" alt="Godot interface with a State Machine Component node and the three states mentioned as children"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once again I tested it again with some friends…. It was good, most people won’t try to &lt;em&gt;cheat&lt;/em&gt; on the very first try, but I want these enemies to be repeated several times, and after the first encounter, most people realized a few &lt;em&gt;simple strategies&lt;/em&gt; to just kill them without a problem:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Fly and shoot&lt;/li&gt;
&lt;li&gt;Attack from a far distance&lt;/li&gt;
&lt;li&gt;Shoot indefinitely &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These needs to be fixed, I do want this enemies to be simple enough to not being frustrating (remember there will be a lot of them) but also I don’t want them to be &lt;em&gt;trivial&lt;/em&gt; to kill to be boring (and so keep the player in &lt;a href="http://whats-in-a-game.com/controlling-flow/" rel="noopener noreferrer"&gt;the flow&lt;/a&gt;).&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%2F9wx4m815d3bps1raf34m.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%2F9wx4m815d3bps1raf34m.png" alt="A graph representing the flow state which grows in balance with skill and difficulty"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To fix fly and shoot, I decided to make a key change that also affects other parts of the game but also makes a lot of sense: If the main character is holding the gun, they can’t manipulate the jetpack at the same time. This also affects the level design (which maybe deserves a different post) opening new possibilities and challenges, so I was happy with it.&lt;/p&gt;

&lt;p&gt;For the second issue (&lt;strong&gt;Attack from a far distance&lt;/strong&gt;) I thought of providing some way to deflect the lasers. Adding a shield (or a lightsaber) would probably make the combat a bit more interesting, but don’t align a lot with the plot of the game (again, that's for another post). Also, it would probably complicate things to a whole new level. So I just made the lasers to deflect each other. If a laser enters the player detection area, the enemy will shoot to deflect it. To make things a bit more interesting, the enemy will walk forward to try to see who’s shooting.&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%2Fklawqvm770wghzmhecff.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%2Fklawqvm770wghzmhecff.png" alt="A FSM representation of the above mentioned states"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, to fix the &lt;strong&gt;shoot indefinitely&lt;/strong&gt;… well, I needed to make it so the player just can’t do it. The gun already has a “pulse the trigger effect” (ie. the player can only fire every 0.5 seconds) but since now the lasers can be used to deflect lasers, you can just hit the trigger like a maniac, and shoots will eventually impact the enemy.&lt;br&gt;
I needed some &lt;em&gt;bullets&lt;/em&gt;… but this add &lt;strong&gt;more balancing problems&lt;/strong&gt;: I'd need to make sure the player won’t just deplete their bullets and then not be able to advance the game. Some games fix this by giving you a weaker weapon that you can use indefinitely (like the knife in &lt;a href="https://en.wikipedia.org/wiki/Resident_Evil" rel="noopener noreferrer"&gt;Resident Evil&lt;/a&gt;) or some areas where you can recharge (Like &lt;a href="https://en.wikipedia.org/wiki/Metroid_Dread" rel="noopener noreferrer"&gt;Metroid Dread&lt;/a&gt;). &lt;br&gt;
The knife might be good but the gun is also used to open some doors and won’t make a lot of sense to open the doors with a knife.&lt;br&gt;
Recharging areas, on the other hand, requires players to fly away from the combat to get to one of those areas. Given the enemies here are humans it would be unrealistic if they just let you go away… and adding a chase &amp;amp; attack system like in &lt;a href="https://en.wikipedia.org/wiki/The_Last_of_Us" rel="noopener noreferrer"&gt;The Last Of Us&lt;/a&gt;, would turn this on a completely different game.&lt;/p&gt;

&lt;p&gt;Turns out the fix was already there… The jetpack already requires a &lt;em&gt;cooldown&lt;/em&gt; period if you try to use it for a long period of time. The laws of energy for this game are already settle so why don’t reuse it for the gun?&lt;br&gt;
That’s it! The gun now has its own energy bar. Same as the jetpack. And given that now you can only use one of the two, makes sense they share the same energy.&lt;br&gt;
This finally makes the combat a bit more interesting… If the player shoots indefinitely, they won’t be vulnerable as they can’t deflect attacks and won’t be able to fly to avoid them as they need the energy to power the backpack as well.&lt;/p&gt;

&lt;p&gt;To sum up this combat system: The player has to shoot to attack the enemy and avoid shoots from the enemy.&lt;br&gt;
For the latter they can shoot to deflect the lasers or fly to avoid them. Both actions take energy so they have to be smart enough to make good use of them without running out of energy and left vulnerable to the enemy’s attack.&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%2Fdqadb8hrnb16yudrf2lx.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%2Fdqadb8hrnb16yudrf2lx.png" alt="Final representation of the FSM with all the mentioned states"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As a last touch, enemies now can have some &lt;em&gt;personality&lt;/em&gt; as they can shoot with different &lt;em&gt;strategies&lt;/em&gt;: shoot on different times, only shoot to deflect, jump and move to difficult aiming or any combination of these.&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%2F8jpo02uuptela9brwem2.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%2F8jpo02uuptela9brwem2.png" alt="In progress game image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Will I stop there? I don't really know. For a minion like enemy I do think this system is good and fun. I do have in mind a few &lt;em&gt;bosses&lt;/em&gt; which will require more tuning, but that's for another round. Now I do have what I need to build a few levels and keep testing.&lt;/p&gt;

&lt;p&gt;If you want to talk about Video Game Development and design, reach me out on X at &lt;a href="//x.com/terradillospab"&gt;@terradillospab&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[1] In the chatGPT era, calling a thing that shoots every certain time and jumps when you jump an AI seems way exaggerated… but it is what it is.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>godot</category>
    </item>
    <item>
      <title>Why I Love Prince Of Persia</title>
      <dc:creator>Pablo Terradillos</dc:creator>
      <pubDate>Tue, 03 Aug 2021 01:08:09 +0000</pubDate>
      <link>https://dev.to/tehsis/why-i-love-prince-of-persia-46c3</link>
      <guid>https://dev.to/tehsis/why-i-love-prince-of-persia-46c3</guid>
      <description>&lt;p&gt;I've always found Prince of Persia a fascinating game. I still play it from start to finish every now and then. If you do the math twice a year ends up adding up.&lt;/p&gt;

&lt;p&gt;I refuse to believe that the reason behind this is that it's among the firsts (if not the first) game I have ever played.&lt;br&gt;
I also think a fundamental skill for a game designer is to understand how the games we love have been able to generate the sensations we feel when we play it and, most important, why they are fun.&lt;br&gt;
In this post, I'll analyze this masterpiece, from the point of view of the player and focusing on the sensations it generates without going deep into details.&lt;/p&gt;
&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;The analysis I make here is not free of nostalgia.&lt;br&gt;
While this game has many ports I think the definitive version is the DOS version, using the EGA color mode and the PC internal speakers. The screenshots used on the article came from this version.&lt;/p&gt;

&lt;p&gt;Now, let's start.&lt;/p&gt;
&lt;h2&gt;
  
  
  Story
&lt;/h2&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%2Fhgp1t050568t9ltdubi2.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%2Fhgp1t050568t9ltdubi2.png" alt="The princess waiting captured on her room is the first and one of the few cutscenes of the game"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The plot of the game is extremely simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Jaffar, the Sultan's Grand Vizier wants the throne and for that, he needs to marry the Sultan's young daughter. He casts a spell over the princess and she has to marry Jaffar or die. Only "the brave youth she loves" can save her, but he's a prisoner in the castle's dungeons.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And for a good period of my youth, this was basically "save the princess from the evil one". Since rarely I kept all the intro through the end (also, I've been playing this game since before I was able to read and English is not even my mother tongue)&lt;/p&gt;

&lt;p&gt;For all it matters, the story gives us purpose: to rescue the princess. But also plays with our anxiety: we know that eventually we will fight Jaffar and get to the princess before the hour runs out.&lt;/p&gt;

&lt;p&gt;Both aspects are equally important, exploring the castle is fun, but we also need to be in line with our mission. This tension came into play at different points in the game. Even when this is in most aspects a linear game, you feel all the time that there's a lot to explore. Though most of the time, diverging from the main path will lead you to death ends (though sometimes you'll get rewarded by increasing your max health)&lt;/p&gt;
&lt;h2&gt;
  
  
  Visuals
&lt;/h2&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%2Fk3euir4glu9lwhlt8ubc.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%2Fk3euir4glu9lwhlt8ubc.png" alt="The animations of the character are extremely fluid"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are talking of a game released in 1989 for a machine that was not intended for video games and developed by a small team yet it has its own identity and does a great job setting the atmosphere. The first three levels, the dungeons, makes you feel locked up and afraid. You can feel the darkness and loneliness our young hero might be feeling. Then you discover a much more colorful area, that resembles more the characteristics of the princess's room seen during the intro. This alternation provides a well received freshness just went the visuals might start to feel monotonous.&lt;/p&gt;

&lt;p&gt;The character animation requires its own paragraph of course as it feels extremely &lt;em&gt;real&lt;/em&gt; (and it is, since it was made from recordings of the author's brother performing the movements) and provides a delightful feedback to the player actions. I always lost a couple of seconds just making the character slide from one side to the other.&lt;/p&gt;
&lt;h2&gt;
  
  
  Game Mechanics
&lt;/h2&gt;

&lt;p&gt;These are less simpler than the history but not by far if you compare it with most games from today.&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%2Fij6wwxmp306ly087sbj2.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%2Fij6wwxmp306ly087sbj2.png" alt="I love the fighting scenes on the game"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can move left or right either running by default or walking when pressing a key. You can also jump straight or forward and combine the running with the jump.&lt;br&gt;
You also have the &lt;em&gt;combat mode&lt;/em&gt; which involves a sword and has a few actions: attack, move right or left, guard or sheath the sword.&lt;br&gt;
Some combats are avoidable if you are clever enough. Well, maybe not too clever, but it's truly rewarding when you make a guard fall into a cliff or get locked behind a door.&lt;/p&gt;

&lt;p&gt;Potions deserves a note aside: most of them will just heal you others will damage you and a few will increase your life meter. There are only two of them that have special effects: the one that makes you fall slower and avoid a certain death and the one that inverts the screen and controls.&lt;br&gt;
This is certainly another important aspect of the game: It does not repeat itself, which leads me to the next section.&lt;/p&gt;
&lt;h2&gt;
  
  
  Music
&lt;/h2&gt;

&lt;p&gt;I've kept music for the last since normally it is something I overlook. But turns out the music in this game (and sound effects in general) are as subtle as any other aspect of the game: There's the main theme, the music for completing a level, the tune played when you die, the one used when you kill a guard and the one played when you drink the fall-slowered potion on level 7.&lt;br&gt;
At any moment the music distracts you as the game doesn't really have a background music. As we discussed for the visuals, the music sets the atmosphere. The absence of music during most of the gameplay adds to the loneliness created by the visuals and helps to empathize with particular events.&lt;/p&gt;

&lt;p&gt;There's one particular tune that makes me shiver and it's a great example of this: On level 4, when you find the mirror, you find yourself shocked and intrigued. It's actually scary when you cross it and the shadow guy appears for the first time. After completing the level, you start hearing the classic end level music... but it suddenly gets cut and an upbeat tune is heard, emphasizing the disturbing moment you have just witnessed.&lt;/p&gt;
&lt;h2&gt;
  
  
  Game events
&lt;/h2&gt;

&lt;p&gt;In every section, we have talked about how each aspect of the games helps to set the tone of the game and how they are wisely used to create an atmosphere or emphasize the &lt;em&gt;Events&lt;/em&gt; in the game.&lt;br&gt;
I call Events to those &lt;em&gt;specific moments&lt;/em&gt; that appear on each level.&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%2Ffbbbcg711u7a53egrbk0.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%2Ffbbbcg711u7a53egrbk0.png" alt="I still shiver with the mirror"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Events in the game are used as plot devices to move the &lt;em&gt;story&lt;/em&gt; forward. Once again, the subtlety on how they are used is the trick here. No Event lasts more than a few seconds and they rarely block the player, they just "happen". If the game was made today, most likely you will get a cut scene for each one of them. Though here you will just continue moving while hearing a particular tone or participating in it.&lt;/p&gt;

&lt;p&gt;Each of these Events makes their corresponding level unique. They normally add their own mechanic to the game and are used only once. They surely disrupt you the first time you play the game and make you wonder what's ahead.&lt;/p&gt;

&lt;p&gt;Just for reference, let's make a quick summary of them:&lt;/p&gt;

&lt;p&gt;Level 1: Get the sword.&lt;br&gt;
Level 2: No events.&lt;br&gt;
Level 3: The Skeleton.&lt;br&gt;
Level 4: The mirror and the shadow.&lt;br&gt;
Level 5: The shadow steals a healing bottle.&lt;br&gt;
Level 6: The Fat Guard and The shadow closes a door making you fall to the dungeons.&lt;br&gt;
Level 7: The floating potion.&lt;br&gt;
Level 8: The passive guard and the mice.&lt;br&gt;
Level 9: The inverse-control potion.&lt;br&gt;
Level 10: No events.&lt;br&gt;
Level 11: The ceiling collapses as you go.&lt;br&gt;
Level 12: Encounter with the shadow.&lt;br&gt;
Level 12+: Fight with Jaffar.&lt;br&gt;
Level 13: Rescue the princess.&lt;/p&gt;
&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Overall, I think the subtlety each element used in the game is what makes this game a masterpiece. The simple story gives you a purpose, the visuals and the music sets a tone of a thriller that gets you engaged, the mechanics provide the fun and the events make the game to not be repetitive and keep you attached to it until the end.&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%2F47zj8xu38i4gtynj08bd.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%2F47zj8xu38i4gtynj08bd.png" alt="Oops, spoiler"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All things considered, Prince of Persia is a perfect example on how a few elements can be used to create a cohesive experience that, wisely used, provides a simple linear game yet with a lot of re playable value.&lt;/p&gt;

&lt;p&gt;If you want to talk about game development, game design or just games in general, please reach me out to &lt;a class="mentioned-user" href="https://dev.to/tehsis"&gt;@tehsis&lt;/a&gt; on Twitter.&lt;br&gt;
For more game development content, follow @alidionstudios so you don't miss out our next publication.&lt;/p&gt;

&lt;p&gt;Now, I'll type the magic words, and play some PoP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\&amp;gt; prince ega
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

</description>
      <category>gamedev</category>
    </item>
    <item>
      <title>Day 1: Planning Ahead</title>
      <dc:creator>Pablo Terradillos</dc:creator>
      <pubDate>Sun, 01 Aug 2021 22:08:15 +0000</pubDate>
      <link>https://dev.to/tehsis/day-1-planning-ahead-1lgf</link>
      <guid>https://dev.to/tehsis/day-1-planning-ahead-1lgf</guid>
      <description>&lt;p&gt;This is going to be a simple development blog for a game I'm working on.&lt;/p&gt;

&lt;p&gt;I'd like to write about the experience but also I don't want to expend a lot of time here and rather be building the real thing.&lt;/p&gt;

&lt;p&gt;The game will be some sort of tribute to the original Prince of Persia, for that, I've made an analysis of the game in another blogpost.&lt;/p&gt;

&lt;p&gt;The first thing I've built is a prototype. I've used that to learn the basis of Unity and also test the mechanics I plan for the game.&lt;br&gt;
First thing is that I want the game to be fun from the moment it starts. I've slightly based on HERO&lt;/p&gt;

&lt;p&gt;I've started with a &lt;a href="https://en.wikipedia.org/wiki/Game_design_document"&gt;GDD&lt;/a&gt; with a format extracted from &lt;a href="https://www.goodreads.com/book/show/8449713-level-up"&gt;Level UP!&lt;/a&gt;. &lt;br&gt;
I'll make it public eventually though is nothing complicated, if you want to take a look at it, just let me know.&lt;/p&gt;

&lt;p&gt;To summarize, Vectoria: Savior,&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Will have 12 levels&lt;/li&gt;
&lt;li&gt;Is expected to be ready in 3 months&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The prototype of the game can be found here: &lt;a href="https://tehsis.itch.io/vectoria"&gt;https://tehsis.itch.io/vectoria&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are a couple of decisions I have already made for the game and won't talk about them right now. For example, I'll be using Unity for the game. Mostly because of the community I have access to.&lt;/p&gt;

&lt;p&gt;So, where to go now? I think I have enough elements to build the real thing. Most of the prototype is just throw away code which helped me to get familiarized with Unity and C#.&lt;/p&gt;

&lt;p&gt;The elements I need to build to support the game are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Game mechanics:

&lt;ul&gt;
&lt;li&gt;Jetpack&lt;/li&gt;
&lt;li&gt;Gun&lt;/li&gt;
&lt;li&gt;Bombs&lt;/li&gt;
&lt;li&gt;breakable doors&lt;/li&gt;
&lt;li&gt;Floor on fire&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Level editor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For each item of the game mechanic I have a description on the GDD, the level editor is something I need to put all elements together. I know there're several plugins on Unity for that so I need to evaluate wether to build one or buy one.&lt;br&gt;
I'll evaluate both options... mostly because the nerd in me tells me to build one.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>From React to SwiftUI</title>
      <dc:creator>Pablo Terradillos</dc:creator>
      <pubDate>Wed, 16 Dec 2020 13:01:28 +0000</pubDate>
      <link>https://dev.to/tehsis/from-react-to-swiftui-4pja</link>
      <guid>https://dev.to/tehsis/from-react-to-swiftui-4pja</guid>
      <description>&lt;p&gt;Some time ago, I've started working on &lt;a href="https://taskmeup.alidion.studio"&gt;TaskMeUp&lt;/a&gt; for which I wanted to provide a native experience beyond a web one.&lt;/p&gt;

&lt;p&gt;I considered lucky that just one year ago, Apple announced SwiftUI, a framework which, on Apple words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;provides views, controls, and layout structures for declaring your app’s user interface. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Something that might sound similar for those of us comming from the web world, since it's quite similar to React (and some other tools and frameworks, of course)&lt;/p&gt;

&lt;p&gt;Truth is that SwiftUI takes a lot of inspiration from React and it's quite similar, though adapted to Apple ecosystem and offering an experience similar to what on the web frontend world would be React + (Mobx)[&lt;a href="https://mobx.js.org/README.html"&gt;https://mobx.js.org/README.html&lt;/a&gt;] + &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; + some &lt;a href="https://github.com/auth0/cosmos"&gt;design system&lt;/a&gt; (Apple's own on this case).&lt;/p&gt;

&lt;h1&gt;
  
  
  Starting with SwiftUI
&lt;/h1&gt;

&lt;p&gt;To start working with SwiftUI we need macOS (on the contrary of the web, Apple's ecosystem is not open)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We open up Xcode&lt;/li&gt;
&lt;li&gt;Select "Create new Xcode project"&lt;/li&gt;
&lt;li&gt;Choose iOS -&amp;gt; App&lt;/li&gt;
&lt;li&gt;We fill in some data, and quite important, select "User interface: SwiftUI"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Xcode will then initialize the project and we will see on its main screen a few files already created. By default, we will have open "ContentView.swift", our first &lt;em&gt;SwiftUI view&lt;/em&gt;&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;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView&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="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&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="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&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="kt"&gt;ContentView&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;We can already compile this and run (cmd + r) on a simulator or even on an device (either iOS, iPadOS or macOS). We can also see to the right or the bottom of the editor (depending on our preferences) a preview of our application/view (most likely you will need to click on "resume" for something to happen, this preview stops working with ease).&lt;br&gt;
Let's take a look at what's going on here:&lt;/p&gt;

&lt;p&gt;The first line &lt;code&gt;import SwiftUI&lt;/code&gt; is clear, we import that framework (Apple's calls frameworks to all its libraries), bringing to our context all of the names and symbols declared there.&lt;/p&gt;

&lt;p&gt;Right after it we see a &lt;code&gt;struct&lt;/code&gt; named &lt;code&gt;ContentView&lt;/code&gt; which implements a &lt;code&gt;protocol&lt;/code&gt; named &lt;code&gt;View&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  protocols, classes, structs, references, etc
&lt;/h1&gt;

&lt;p&gt;Let's start from the simplest one: a &lt;code&gt;protocol&lt;/code&gt; is similar to what in Typescript or Java is called an &lt;code&gt;interface&lt;/code&gt;. That is to say, a &lt;em&gt;contract&lt;/em&gt;, we are stating our &lt;code&gt;struct&lt;/code&gt; will have a set of specific attributes and/or methods. You can't declare types on javascript so there's not an equivalent for this other than documenting (or doing a runtime check) what properties or methods an specific object will have.&lt;br&gt;
By saying that &lt;code&gt;ContentView&lt;/code&gt; implements the View &lt;code&gt;protocol&lt;/code&gt;, we can use ContentView anywhere a View is expected.&lt;/p&gt;

&lt;p&gt;Let's move on to the &lt;code&gt;struct&lt;/code&gt;: This is similar to a &lt;code&gt;class&lt;/code&gt; in Javascript and an instance of this &lt;code&gt;struct&lt;/code&gt; is similar to an object. There's one caveat though: on Swift, &lt;strong&gt;structs instances will be always passed as values&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What does that means? If we pass our &lt;em&gt;object&lt;/em&gt;, via a function call or an assigment, this object will be copied and the function or the new symbol will get &lt;em&gt;a copy&lt;/em&gt; of it.&lt;br&gt;
On Javascript, objects are always passed by &lt;em&gt;reference&lt;/em&gt;, that means that what we pass is actually a &lt;a href="https://en.wikipedia.org/wiki/Pointer_(computer_programming)"&gt;pointer&lt;/a&gt; to the memory space that holds the object and not the object itself.&lt;/p&gt;

&lt;p&gt;let's take a look&lt;/p&gt;

&lt;p&gt;On Javascript,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pablo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;anotherUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;

&lt;span class="nx"&gt;anotherUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Emiliano&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Emiliano"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anotherUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Emiliano"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Swift,&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;struct&lt;/span&gt; &lt;span class="kt"&gt;User&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pablo"&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;anotherUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Emiliano"&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Pablo"&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;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Emiliano"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While it's not present on the code we are analizing, Swift provides &lt;code&gt;class&lt;/code&gt;, which we can say is similar to a &lt;code&gt;struct&lt;/code&gt; which values are passed by &lt;em&gt;reference&lt;/em&gt; (on the same way than Javascript).&lt;br&gt;
The syntax is quite similar than the previous example,&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;class&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;}&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pablo"&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;anotherUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Emiliano"&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Emiliano"&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;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Emiliano"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;You can also notice that I had to make two changes: specify the name attribute as &lt;code&gt;public&lt;/code&gt; (by default on classes these are private) and define a constructor (yes, &lt;code&gt;init&lt;/code&gt; method is to Swift's classes what &lt;code&gt;construct&lt;/code&gt; is on Javascript ones)&lt;/p&gt;

&lt;p&gt;Let's get back to the initial SwiftUI code. As a sole property of this &lt;code&gt;struct&lt;/code&gt; we have &lt;code&gt;body&lt;/code&gt;. On this case, the ":" (from &lt;code&gt;var body: some View&lt;/code&gt;) are telling us that &lt;code&gt;body&lt;/code&gt; conforms to... &lt;em&gt;some view&lt;/em&gt;.&lt;br&gt;
We can read this literally, body is some view, &lt;em&gt;we don't care which one&lt;/em&gt;.&lt;br&gt;
Once again this is something that won't have a purpose on javascript or any other not strongly typed language, though a valid question is "what's the different between &lt;code&gt;some View&lt;/code&gt; and just &lt;code&gt;View&lt;/code&gt; if in both cases &lt;code&gt;View&lt;/code&gt; is a &lt;code&gt;protocol&lt;/code&gt;?&lt;br&gt;
Well, &lt;code&gt;some View&lt;/code&gt; is more similar to a &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html"&gt;generic type&lt;/a&gt;. By specyfing &lt;code&gt;some View&lt;/code&gt; we are stating that this variable is of an specific View type, not just any View.&lt;/p&gt;

&lt;p&gt;For example, the following example will throw an error&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;protocol&lt;/span&gt; &lt;span class="kt"&gt;Greeter&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;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Greeter&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;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Greeter&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;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Howdy!"&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 function is invalid&lt;/span&gt;
&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;Greeter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&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;User&lt;/span&gt;&lt;span class="p"&gt;()&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;Person&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;Here &lt;code&gt;test&lt;/code&gt; is trying to return either an &lt;code&gt;User&lt;/code&gt; or a &lt;code&gt;Person, both of them implements&lt;/code&gt;Greeter&lt;code&gt;though by specifiend that&lt;/code&gt;test&lt;code&gt;returns&lt;/code&gt;some Greeter&lt;code&gt;we are saying that it returns an specific type and on our example it can be an&lt;/code&gt;User&lt;code&gt;or a&lt;/code&gt;Person&lt;code&gt;, not both.&lt;br&gt;
If we clear the word&lt;/code&gt;some`, the example will compile successfully.&lt;/p&gt;

&lt;h1&gt;
  
  
  Computed properties
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;body&lt;/code&gt; has more secrets, it immediately opens a curly braces that surrounds a piece of code.&lt;br&gt;
This is known as &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID259"&gt;Computed Properties&lt;/a&gt;, which is equivalent to &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get"&gt;getter&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set"&gt;setters&lt;/a&gt; methods of javascript.&lt;br&gt;
On this case, since we are not specifying how to assign a new value to body, it's a getter.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
struct Person {&lt;br&gt;
    var name: String&lt;br&gt;
    var yearOfBirth: Int&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var age: Int {
    2020 - yearOfBirth
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;var p = Person(name: "Pablo", yearOfBirth: 1987)&lt;/p&gt;

&lt;p&gt;print(p.age) // 33 &lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What's inside the curly braces is just a function. Swift loves to eliminate redundant code, that's why on single line functions, the result of that line is returned (when you have more lines, you'll need to add &lt;code&gt;return 2020 - yearOfBirth&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;Last but not least (finally!), &lt;code&gt;body&lt;/code&gt; returns &lt;code&gt;Text("Hello world")&lt;/code&gt;. If we do "option + click" on  Text, we will see that this is a &lt;code&gt;struct&lt;/code&gt; that implements &lt;code&gt;View&lt;/code&gt; (which was expected since we are declaring that body will return &lt;code&gt;some View&lt;/code&gt;)&lt;/p&gt;

&lt;h1&gt;
  
  
  Views and Components
&lt;/h1&gt;

&lt;p&gt;We can say that &lt;code&gt;Text("Hello world")&lt;/code&gt; is a component, like React components. SwiftUI knows exactly how to show it, with which style and on what position (even considering if it's running on an iPhone, Apple Watch, Apple TV, etc).&lt;br&gt;
SwifUI provides of course a lot of components and we can also define our owns. Actually on this example, &lt;code&gt;ContentView&lt;/code&gt; is a component just like Text is.&lt;/p&gt;

&lt;p&gt;For example, let's surround our Hello World on a &lt;code&gt;List&lt;/code&gt; component&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`swift&lt;br&gt;
struct ContentView: View {&lt;br&gt;
    var body: some View {&lt;br&gt;
        List {&lt;br&gt;
            Text("Hello, World!")&lt;br&gt;
        }&lt;br&gt;
    }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;br&gt;
And we can see how our application has changed.&lt;/p&gt;

&lt;p&gt;We can also make our Text clickable/tapable using a &lt;code&gt;Button&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;swift&lt;br&gt;
struct ContentView: View {&lt;br&gt;
  var body: some View {&lt;br&gt;
    List {&lt;br&gt;
      Button(action: {&lt;br&gt;
        print("Hi")&lt;br&gt;
      }) {&lt;br&gt;
        Text("Hello, world!")&lt;br&gt;
      }&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
Now everyime we click (or tap) our text, we will see "Hi!" on Xcode debug console.&lt;/p&gt;

&lt;p&gt;Worth noticing that all views has methods to change their styling. Eg. we can do &lt;code&gt;Text(...).fontWeight(.bold)&lt;/code&gt; to show that text in bold.&lt;/p&gt;

&lt;h1&gt;
  
  
  Extra
&lt;/h1&gt;

&lt;h2&gt;
  
  
  parameters labels
&lt;/h2&gt;

&lt;p&gt;As you might have seen, when calling a function in Swift, parameters also indicates its names. Swift allow us to define labels on the parameters ans even define different names for the implemenation and the calling:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`swift&lt;br&gt;
getAvatar(for: "Pablo")&lt;/p&gt;

&lt;p&gt;func getAvatar(for user: String) {&lt;br&gt;
  // ...&lt;br&gt;
  // user -&amp;gt; "Pablo"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I can omit the &lt;code&gt;for&lt;/code&gt; label and use it as &lt;code&gt;getAvatar(user: "Pablo")&lt;/code&gt; or just use an _ to completely omit the name, but it won't read as good.&lt;/p&gt;

&lt;h2&gt;
  
  
  Functions as last parameter
&lt;/h2&gt;

&lt;p&gt;I'm not exactly sure how this is called, though something that originally confused me on swift, are cases like the one we have in Button above&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;swift&lt;br&gt;
 Button(action: {&lt;br&gt;
    print("Hi!")&lt;br&gt;
   }) {&lt;br&gt;
     Text("Hello, World!")&lt;br&gt;
   }&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Like Javascript, Swift can use functions as first class citizens, pass them as values and therefore our functions can accept them as parameters. What's courious is that when the function is also the last argument of the function, you can completely omit the label and write the function outside of the parenthesis:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`swift &lt;br&gt;
func doSomething(value: Int, method: (Int) -&amp;gt; ()) {&lt;br&gt;
  method(value)&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;doSomething(value: 5) { val in&lt;br&gt;
  print(val) // 5&lt;br&gt;
}&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We can also be explicit of course&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;swift&lt;br&gt;
doSomething(value: 5, method: { val in&lt;br&gt;
  print(val) // 5&lt;br&gt;
})&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Final thoughts
&lt;/h1&gt;

&lt;p&gt;SwiftUI has a similar premise than React: Our view is a function of our state and views are composed from other views.&lt;br&gt;
Much of the mindset you used on React can be used on SwiftUI as well.&lt;br&gt;
Xcode also provides a lot of guidelines to help us writing our code as well.&lt;/p&gt;

&lt;p&gt;Also, SwiftUI makes it easier to follow Apple conventions and write a &lt;em&gt;decent looking&lt;/em&gt; UI that adapts to the system (ie. font changes, dark mode, etc) with almost 0 effort from our side.&lt;br&gt;
The major caveat at this point is that the whole platform is not &lt;em&gt;stable&lt;/em&gt; as we would like. On each new OS version (or even Xcode versions) things might breaks on mysterious ways or just behave differently, so I think that while is not strictly required, a deeper understanding of the Apple's &lt;em&gt;previous&lt;/em&gt; UI framework UIkit is still valuable when working on mid to large sized apps. &lt;/p&gt;

&lt;p&gt;If you have reached this far and you are interested on learning about Swift or SwiftUI, these are some great resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.hackingwithswift.com/100/swiftui"&gt;100 days of SwiftUI&lt;/a&gt; by Paul Hudson&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/watch?v=jbtqIBpUG7g"&gt;Standford CS193p classes&lt;/a&gt; on SwiftUI&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/videos/play/wwdc2019/216/"&gt;Apple's introduction to SwiftUI on WWDC 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/tutorials/swiftui/"&gt;Apple's tutorials on SwiftUI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are interested on Software engineering and the web, you can reach me on twitter as &lt;a href="https://twitter.com/tehsis"&gt;@tehsis&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sobre-analizando el hello world de SwiftUI, desde javascript</title>
      <dc:creator>Pablo Terradillos</dc:creator>
      <pubDate>Tue, 04 Aug 2020 13:47:34 +0000</pubDate>
      <link>https://dev.to/tehsis/sobre-analizando-el-hello-world-de-swiftui-desde-javascript-l5m</link>
      <guid>https://dev.to/tehsis/sobre-analizando-el-hello-world-de-swiftui-desde-javascript-l5m</guid>
      <description>&lt;p&gt;Hace unos días comencé a trabajar en un proyecto personal que, por motivos que comentare en otro post, espero, decidí desarrollarlo de forma nativa para iOS (ademas de su versión web, claro)&lt;/p&gt;

&lt;p&gt;Por suerte para mí, en 2019, Apple anuncio SwiftUI, un framework que, &lt;a href="https://developer.apple.com/documentation/swiftui"&gt;en palabras de Apple&lt;/a&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Ofrece vistas, controles y estructuras de diseño para declarar la interface de tus applicaciones". &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Una definición, &lt;strong&gt;que para los que venimos del mundo web, nos puede sonar a la de &lt;a href="https://reactjs.org/"&gt;React&lt;/a&gt;&lt;/strong&gt; (y bueno, de varios otros frameworks tambien).&lt;/p&gt;

&lt;p&gt;Lo cierto es que SwiftUI toma mucho de React y, en esencia, es muy parecido. Claro que, adaptado al ecosistema Apple y ofreciendo una experiencia muy similar a lo que, en el mundo web frontend, seria similar a usar React + &lt;a href="https://mobx.js.org/"&gt;Mobx&lt;/a&gt; + &lt;a href="https://storybook.js.org/"&gt;Storybook&lt;/a&gt; + algun &lt;a href="https://auth0-cosmos.now.sh/"&gt;"design system"&lt;/a&gt; (en este caso, el design system de Apple).&lt;/p&gt;

&lt;h1&gt;
  
  
  Comenzando
&lt;/h1&gt;

&lt;p&gt;Comenzar con SwiftUI es bastante simple (obviamente, es requerimiento contar con macOS, a diferencia de la web, el ecosistema de Apple no esta pensado para ser abierto):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Abrimos Xcode&lt;/li&gt;
&lt;li&gt;Seleccionamos "Create a new Xcode project" / "Crear nuevo proyecto de Xcode"&lt;/li&gt;
&lt;li&gt;Elegimos como template "Single View App"&lt;/li&gt;
&lt;li&gt;Llenamos un par de datos y, muy importante, seleccionamos "User Interface: SwiftUI"&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Xcode inicializa el proyecto y vemos su pantalla principal y varios archivos creados. Por defecto, tendremos abierto "ContentView.swift", nuestra primera &lt;em&gt;vista de SwiftUI&lt;/em&gt;.&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;SwiftUI&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView&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="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&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="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView_Previews&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;PreviewProvider&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;previews&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="kt"&gt;ContentView&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;Esto ya podemos compilarlo y correrlo en un simulador o incluso en un dispositivo iOS/iPadOS/macOS. Ademas veremos a la derecha o debajo del editor, dependiendo del tamaño de la ventana, un preview de nuestra aplicación/vista (seguramente haya que hacer click en "resume" para comenzar a ver algo)&lt;br&gt;
Pero veamos un poco que esta pasando acá.&lt;/p&gt;

&lt;p&gt;La primer linea &lt;code&gt;import SwiftUI&lt;/code&gt; es bastante clara, incluye dicha librería/framework.&lt;/p&gt;

&lt;p&gt;Luego vemos un &lt;code&gt;struct&lt;/code&gt; llamado &lt;code&gt;ContentView&lt;/code&gt; que implementa un &lt;code&gt;protocol&lt;/code&gt; de nombre &lt;code&gt;View&lt;/code&gt;:&lt;/p&gt;
&lt;h1&gt;
  
  
  protocolos, clases estructuras, referencias, etc
&lt;/h1&gt;

&lt;p&gt;Vamos por lo más sencillo: un &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/Protocols.html"&gt;&lt;code&gt;protocol&lt;/code&gt;&lt;/a&gt; es, ni más ni menos, lo que en Typescript o Java es una &lt;a href="https://www.typescriptlang.org/docs/handbook/interfaces.html"&gt;&lt;code&gt;interface&lt;/code&gt;&lt;/a&gt;. Es decir, un contrato, estamos diciendo que nuestra &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html"&gt;&lt;code&gt;struct&lt;/code&gt;&lt;/a&gt; tiene una serie de atributos específicos. Javascript no posee tipos, por tanto no tenemos un equivalente directo más allá de usar un objeto y "confiar" (o chequearlo en runtime) que tendrá un determinado método o propiedad.&lt;/p&gt;

&lt;p&gt;Sigamos por el &lt;code&gt;struct&lt;/code&gt;: Esto equivale a una &lt;code&gt;class&lt;/code&gt; en Javascript y una instancia de este &lt;code&gt;struct&lt;/code&gt; equivaldría a un objeto. Pero hay una pequeña &lt;em&gt;trampa&lt;/em&gt;.&lt;br&gt;
En Swift las instancias de &lt;code&gt;structs&lt;/code&gt; &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html"&gt;&lt;strong&gt;Siempre se pasan por valor&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;¿Que quiere decir eso? que si pasamos nuestro &lt;em&gt;objeto&lt;/em&gt;, mediante una llamada a una función o una asignación, este objeto se copiará y la función recibirá una nueva &lt;em&gt;copia&lt;/em&gt; del mismo. &lt;br&gt;
En Javascript, los objetos siempre se pasan por &lt;em&gt;referencia&lt;/em&gt;, es decir, lo que pasamos en realidad es un &lt;a href="https://es.wikipedia.org/wiki/Puntero_(inform%C3%A1tica)"&gt;&lt;em&gt;puntero&lt;/em&gt;&lt;/a&gt; al espacio de memoria del objeto y no el objeto en sí.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pablo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;anotherUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;

&lt;span class="nx"&gt;anotherUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Juan&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Juan"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;anotherUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Juan"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mientras que en Swift:&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;struct&lt;/span&gt; &lt;span class="kt"&gt;User&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pablo"&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;anotherUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Juan"&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Pablo"&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;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Juan"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si bien no esta presente en el código que estamos analizando, Swift posee &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/ClassesAndStructures.html"&gt;&lt;code&gt;class&lt;/code&gt;&lt;/a&gt;, que podriamos decir es lo mismo que un &lt;code&gt;struct&lt;/code&gt; pero cuyos valores son pasados por referencia (sí, de la misma forma que ocurre en Javascript). La sintaxis es prácticamente la misma y el ejemplo anterior podemos verlo simplemente reemplazando &lt;code&gt;struct&lt;/code&gt; por &lt;code&gt;class&lt;/code&gt;.&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;class&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

    &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
    &lt;span class="p"&gt;}&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pablo"&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;anotherUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Juan"&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;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Juan"&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;anotherUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// "Juan"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como puede verse, también tuve que hacer dos cosas: especificar que el atributo &lt;code&gt;name&lt;/code&gt; es publico (en las clases por defecto son privados) y definir un constructor (sí, el metodo &lt;code&gt;init&lt;/code&gt; es similar al &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes"&gt;&lt;code&gt;construct&lt;/code&gt; de las &lt;code&gt;class&lt;/code&gt; de Javascript&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Pero volvamos al código inicial de SwiftUI. Como unica propiedad de este &lt;code&gt;struct&lt;/code&gt;, tenemos a &lt;code&gt;body&lt;/code&gt;. En este caso, los ":" (de &lt;code&gt;var body: some view&lt;/code&gt;) nos indica el tipo de &lt;code&gt;body&lt;/code&gt;... &lt;code&gt;some View&lt;/code&gt;.&lt;br&gt;
Esto podríamos leerlo literalmente: body es "alguna" View, no importa cual. &lt;br&gt;
Nuevamente, en Javascript no tenemos nada parecido, porque no tenemos tipos. Pero pensando en Typescript o Java, podriamos preguntarnos: ¿Cual es la diferencia entre &lt;code&gt;some View&lt;/code&gt; o directamente &lt;code&gt;View&lt;/code&gt; siendo que &lt;code&gt;View&lt;/code&gt; es un &lt;code&gt;protocol&lt;/code&gt;?&lt;br&gt;
La respuesta, es que &lt;code&gt;some View&lt;/code&gt; &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/OpaqueTypes.html"&gt;es más similar a un tipo genérico (o generics)&lt;/a&gt;. Al especificar &lt;code&gt;some View&lt;/code&gt; estamos diciendo que esa variable es de un tipo especifico de View, no cualquier View.&lt;/p&gt;

&lt;p&gt;Por ejemplo, el siguiente ejemplo es invalido:&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;protocol&lt;/span&gt; &lt;span class="kt"&gt;Greeter&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;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Greeter&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;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Hello"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Greeter&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;greet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Howdy!"&lt;/span&gt;
    &lt;span class="p"&gt;}&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;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kd"&gt;some&lt;/span&gt; &lt;span class="kt"&gt;Greeter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5&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;User&lt;/span&gt;&lt;span class="p"&gt;()&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;Person&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;En este caso, &lt;code&gt;test&lt;/code&gt; intenta retornar un &lt;code&gt;User&lt;/code&gt; o un &lt;code&gt;Person&lt;/code&gt;, ambos implementan &lt;code&gt;Greeter&lt;/code&gt;, pero al especificar que &lt;code&gt;test&lt;/code&gt; retorna &lt;code&gt;some Greeter&lt;/code&gt;, estamos diciendo que retorna un tipo especifico (en el ejemplo, podría ser un &lt;code&gt;User&lt;/code&gt; o un &lt;code&gt;Person&lt;/code&gt;, pero no ambos.&lt;br&gt;
Si borramos la palabra &lt;code&gt;some&lt;/code&gt;, el ejemplo compila correctamente.&lt;/p&gt;
&lt;h1&gt;
  
  
  Computed properties
&lt;/h1&gt;

&lt;p&gt;Pero &lt;code&gt;body&lt;/code&gt; sigue sorprendiendo, ya que directamente abre una llave que encierra un bloque de código.&lt;br&gt;
Esto es lo que Swift llama &lt;a href="https://docs.swift.org/swift-book/LanguageGuide/Properties.html#ID259"&gt;"Computed properties"&lt;/a&gt;, equivalentes a los &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get"&gt;getter&lt;/a&gt; y &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set"&gt;setters&lt;/a&gt; de Javascript. En este caso, al no especificar como asignar un nuevo valor a body, es simplemente un getter.&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;struct&lt;/span&gt; &lt;span class="kt"&gt;Person&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;yearOfBirth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="mi"&gt;2020&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;yearOfBirth&lt;/span&gt;
    &lt;span class="p"&gt;}&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;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pablo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;yearOfBirth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1987&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;p&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 33 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lo que esta dentro de las llaves es simplemente una función. A Swift le encanta eliminar código redundante, por lo que en funciones de una sola linea, el resultado de dicha expresión es retornado (si hubiese más lineas, debería poner &lt;code&gt;return 2020 - yearOfBirth&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Por último (¡al fin!), &lt;code&gt;body&lt;/code&gt; retorna &lt;code&gt;Text("Hello world")&lt;/code&gt;. Si hacemos "option + click" en Text, veremos que es una &lt;code&gt;struct&lt;/code&gt; que implementa View (como era de esperarse dado que &lt;code&gt;body&lt;/code&gt; es de tipo &lt;code&gt;some View&lt;/code&gt;).&lt;/p&gt;

&lt;h1&gt;
  
  
  Views y Components
&lt;/h1&gt;

&lt;p&gt;Podríamos decir que &lt;code&gt;Text("Hello world")&lt;/code&gt; es un componente, como los componentes de React. SwiftUI sabe exactamente como mostrarlo, con que estilo y en que posición. De igual forma, existen varios componentes con distintos fines. Por ejemplo, encerremos nuestro Hello World en un &lt;code&gt;List&lt;/code&gt;&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;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView&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="kt"&gt;List&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;"Hello, World!"&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;/div&gt;



&lt;p&gt;y veremos como cambió nuestra aplicación.&lt;br&gt;
También podríamos hacer nuestro Texto "clickeable" usando un &lt;code&gt;Button&lt;/code&gt;.&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;struct&lt;/span&gt; &lt;span class="kt"&gt;ContentView&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="kt"&gt;List&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="nv"&gt;action&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="s"&gt;"Hi!"&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="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&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;/div&gt;



&lt;p&gt;Ahora, cada vez que clickeemos (o tapeemos) nuestro texto, veremos "Hi!" en la consola de debug.&lt;/p&gt;

&lt;p&gt;Casi todas las vistas tienen métodos para cambiar sus estilos. Por ejemplo, podemos hacer &lt;code&gt;Text(...).fontWeight(.bold)&lt;/code&gt; para mostrar el texto en negrita.&lt;/p&gt;

&lt;h1&gt;
  
  
  Curiosidades varias
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Etiquetas de parametros
&lt;/h2&gt;

&lt;p&gt;Como habrás visto, al llamar una función en Swift, los parámetros indican el nombre. Swift permite definir &lt;code&gt;etiquetas&lt;/code&gt; a los parámetros e incluso definir nombres distintos para la llamada y la implementación:&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="nf"&gt;getAvatar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;for&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Pablo"&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;getAvatar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="c1"&gt;// user -&amp;gt; "Pablo"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si en la definición omito el &lt;code&gt;for&lt;/code&gt;, tendria que llamar &lt;code&gt;getAvatar(user: "Pablo")&lt;/code&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Funciones como último parametro
&lt;/h2&gt;

&lt;p&gt;No se exactamente como se llama esto, pero algo curioso de Swift y que hizo que inicialmente me cueste leer el código, es el caso de &lt;code&gt;Button&lt;/code&gt; más arriba:&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="kt"&gt;Button&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;action&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="s"&gt;"Hi!"&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="kt"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, World!"&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;¿Que es exactamente lo que rodea a &lt;code&gt;Text&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Al igual que en javascript, Swift permite pasar funciones como valores y por tanto nuestras funciones pueden aceptar funciones como parámetros. Lo curioso, es que en aquellos casos que el último parámetro de la función sea otra función, podemos usar las llaves por fuera del paréntesis.&lt;/p&gt;

&lt;p&gt;Como siempre, mejor un ejemplo:&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;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;in&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;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tambien podriamos llamar a doSomething siendo explicitos:&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="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="k"&gt;in&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;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;SwiftUI parte de una premisa muy similar a la de React: &lt;em&gt;nuestra vista es una función de nuestro estado&lt;/em&gt; y &lt;em&gt;las vistas se componen de otras vistas&lt;/em&gt; (De igual manera que los componentes se componen de otros componentes). Hacer una transición podría decirse que es relativamente sencilla y podemos re-usar mucho de dicho mundo.&lt;br&gt;
Ademas, Xcode nos dara la suficiente ayuda para entender fácilmente que Views y que modificadores tenemos disponibles para armar nuestra aplicación. (cuando no falla, hay que decirlo).&lt;/p&gt;

&lt;p&gt;Si llegaste hasta acá, te recomiendo que mires la introducción oficial de Apple a SwiftUI que seguramente es mucho más clara y extensa que este articulo: &lt;a href="https://developer.apple.com/videos/play/wwdc2019/216/"&gt;https://developer.apple.com/videos/play/wwdc2019/216/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Más adelante veremos como manejar estado dentro de SwiftUI usando el framework "Combine" de Apple (que, siguiendo con analogías, podríamos decir es similar a Mobx)&lt;/p&gt;

&lt;p&gt;Si te interesa el desarrollo web y/o apps, ¡hablemos! Podes seguirme en twitter como &lt;a href="https://twitter.com/tehsis"&gt;@tehsis&lt;/a&gt; &lt;/p&gt;

</description>
      <category>swift</category>
      <category>javascript</category>
      <category>react</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
