<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Maz Development Directory</title><link href="https://mazyod.com/" rel="alternate"></link><link href="https://mazyod.com/feeds/all.atom.xml" rel="self"></link><id>https://mazyod.com/</id><updated>2023-11-28T20:50:23+00:00</updated><entry><title>Ignorance is a Blister</title><link href="https://mazyod.com/blog/2023/11/28/ignorance-is-a-blister/" rel="alternate"></link><published>2023-11-28T20:50:23+00:00</published><updated>2023-11-28T20:50:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2023-11-28:/blog/2023/11/28/ignorance-is-a-blister/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is yet another reboot of the attempt to dish out more fast-paced,
short-form content in order to keep the ball rolling. Previous attempts have not
been successful, so my hopes are not high, but I&amp;rsquo;m going to give it another shot
anyway.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it for the …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is yet another reboot of the attempt to dish out more fast-paced,
short-form content in order to keep the ball rolling. Previous attempts have not
been successful, so my hopes are not high, but I&amp;rsquo;m going to give it another shot
anyway.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s it for the introduction.&lt;/p&gt;
&lt;h2&gt;Good Ignorance&lt;/h2&gt;
&lt;p&gt;The saying goes, &amp;ldquo;Ignorance is bliss&amp;rdquo;, and for good reason. Ignorance of bad
information is generally good. If you are not aware of certain suffering that is
going on in the world, or some ugly truth about a person you know, you are in
bliss.&lt;/p&gt;
&lt;p&gt;This also applies to programming to a certain degree in certain contexts. For
example, PHP. I&amp;rsquo;m really sorry, but if you were a developer back in 2009, and
you started your programming journey with PHP, you probably had to unlearn a lot
of stuff to get back on track, in order to then improve from there. It was not a
language that promoted clean and simple code design.&lt;/p&gt;
&lt;p&gt;Being ignorant of PHP in the 2000s was a bliss.&lt;/p&gt;
&lt;p&gt;The final good ignorance I&amp;rsquo;ll mention in programming is the ignorance of future
problems. Back when I was an inexperienced developer, not even aware of Git, I
used to ship &amp;ldquo;apps&amp;rdquo; on regular basis. They were simple apps, however, they were
useful in their own right. They provided a good starting point to grow from. I
feel like I was shipping for the sake of shipping, even though the final
products were imperfect (to say the least).&lt;/p&gt;
&lt;p&gt;Nowadays, I spend a week figuring out which VS Code extension will work best for
Python linting before I even write a single line of code&amp;hellip; You may not see it
as an &amp;ldquo;ignorance&amp;rdquo; problem per se, but I beg to differ. The fact that I know
about linting in the first place and care about it is partially the reason why
I&amp;rsquo;m having such issues.&lt;/p&gt;
&lt;h2&gt;Bad Ignorance&lt;/h2&gt;
&lt;p&gt;The main reason for this post, however, is to talk about the bad ignorance that
has also plagued me recently in multiple ways.&lt;/p&gt;
&lt;h3&gt;SQLAlchemy&lt;/h3&gt;
&lt;p&gt;I made a career transition from an iOS developer to a Python/Fullstack developer
when I started my current job. Needless to say, I had a lot to learn, and little
time to do so. Granted, I already built a backend for my Dama King game,
however, it was in a hustler fashion, just to get the game out the door. I
didn&amp;rsquo;t spend the time to learn each technology I used in depth.&lt;/p&gt;
&lt;p&gt;My job is in AI/ML, so naturally, I had to use python for most of my work.
Thankfully, I already built many internal tools in Python as an iOS developer,
so I was familiar with the language. However, I never really had to deal with a
database in any significant way. So, the first problem I was faced with was,
which ORM should I use?&lt;/p&gt;
&lt;p&gt;Hold on, which ORM to use? What about using raw SQL? That wasn&amp;rsquo;t even an option
I entertained at all. I thought it was a no-brainer to use an ORM, period. Now,
given that an ORM was a must, I had been to many python meetups, and everyone
swears by SQLAlchemy. So, I went with that. I remember posting a message in a
group chat asking for advice on how to learn the basics of SQLAlchemy for CRUD,
and one guy said, &amp;ldquo;O V E R K I L L L&amp;rdquo;. I was adamant to use it anyway.&lt;/p&gt;
&lt;p&gt;Here is where the lesson begins. I didn&amp;rsquo;t spend nearly enough time learning
SQLAlchemy, and jumped in head first, flat on my face.&lt;/p&gt;
&lt;p&gt;My biggest mistake was not learning SQL first. &amp;ldquo;Seriously, you don&amp;rsquo;t know SQL?&amp;rdquo;,
I hear you say. I knew the basics, just like any other developer, however, the
nuances of SQL were lost on me. Window functions, CTEs, JSON, useful EXISTS
subqueries, etc.&lt;/p&gt;
&lt;p&gt;Why was that an issue? Well, I kept fighting SQLAlchemy, trying to make it do
things that simply don&amp;rsquo;t make sense in SQL, so how can SQLAlchemy do it? Two, or
three, years into my job is when I finally took a step back and decided that I
should craft SQL queries at a lower level to control exactly what would
SQLAlchemy would generate. Thankfully, we were using SQLAlchemy 1.14, which
started a transition to SQLAlchemy 2.0 syntax. This was great since SQLA 2.0
uses a more SQL-like syntax, for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;sa&lt;/span&gt;

&lt;span class="c1"&gt;# we have a repo class that wraps sqla engine.&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyTable&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;War Stories&lt;/h3&gt;
&lt;p&gt;My biggest problem was with SQLAlchemy. The mere fact that it lingered for years
before I finally realized I should learn me some SQL, is just mind boggling. I
have similar war stories, albeit not as bad, with other technologies.&lt;/p&gt;
&lt;p&gt;For example, I don&amp;rsquo;t know why I felt I should try hard to always use the docker
images provided by the official maintainers of the technology I&amp;rsquo;m using. I used
FastAPI&amp;rsquo;s, jupyterlab&amp;rsquo;s, and other images provided by the maintainers, which I
would then extend to add my own customizations. This left me wasting a ton of
time trying to figure out how each base image worked, and how to adapt it to my
needs. Soon enough, we built our own solid base image, which became the
foundation for all our services.&lt;/p&gt;
&lt;p&gt;Another example is Yup (a schema validation library for JavaScript). I thought
it was simple enough to use without reading the docs, nor preparing a sandbox
environment to test it out. Boy, was I wrong. I wasted hours (days?) wrangling
with it, and each time, I tested it against the UI with Formik, which made it
even more difficult to debug. I eventually created a sandbox environment and
used that to test out my schemas before using them in the project. The speed of
feedback was critical in this case.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In conclusion, the lesson I impart to you is to realize when you are wasting
more time than necessary on a technology that you&amp;rsquo;re treating as some sort of
black box, when you should instead take a step back and learn the basics first.&lt;/p&gt;</content><category term="software-engineering"></category></entry><entry><title>Skinning a Cat</title><link href="https://mazyod.com/blog/2023/11/25/skinning-a-cat/" rel="alternate"></link><published>2023-11-25T20:50:23+00:00</published><updated>2023-11-25T20:50:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2023-11-25:/blog/2023/11/25/skinning-a-cat/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I find the saying &amp;ldquo;There&amp;rsquo;s more than one way to skin a cat&amp;rdquo;, just as much as the
next guy, quite morbid and gruesome. And yet, I like to use it and tell myself
that people aren&amp;rsquo;t really skinning cats for sport or professionally, it&amp;rsquo;s just …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I find the saying &amp;ldquo;There&amp;rsquo;s more than one way to skin a cat&amp;rdquo;, just as much as the
next guy, quite morbid and gruesome. And yet, I like to use it and tell myself
that people aren&amp;rsquo;t really skinning cats for sport or professionally, it&amp;rsquo;s just a
saying. So the cat we are going to skin today is Visual Studio Code.&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t believe I somehow, completely off-handedly and irresponsibly, added yet
another opinion to the heated question of whether VS Code is an Editor or an
IDE. I&amp;rsquo;m making a case it&amp;rsquo;s a cat, apparently.&lt;/p&gt;
&lt;h2&gt;Digging Tunnels&lt;/h2&gt;
&lt;p&gt;We recently got hold of the hottest piece of hardware on the market these days..
The glorious A100 GPU. Granted, the H100 eclipsed it, and next year we will see
the H200 and B100, however, for simple people like myself, the A100 is the best
hardware I could realistically expect to work with. Now, we have it.&lt;/p&gt;
&lt;p&gt;This beast of a hardware has been installed in a data center at an undisclosed
location somewhere on earth, and attached to a Linux VM for us to use it
through. As soon as we were given access, we immediately fired up our browsers,
navigated to the JupyterLab service we previously prepared on this VM, and
started mining crypto in the name of &amp;ldquo;Benchmarking the System&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;JK, of course, I would never admit to such illegal use of company hardware
&lt;em&gt;pfft&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;OK, in all honesty, we simply logged in to JupyterLab, pulled some 7B, 13B, 30B,
and 70B parameter LLMs, and let &amp;lsquo;em rip on the GPU.&lt;/p&gt;
&lt;p&gt;We .. Were .. Blown .. Away.&lt;/p&gt;
&lt;p&gt;The fact that high quality models, like the &lt;a href="https://ollama.ai/library/llama2:13b"&gt;llama2 13B&lt;/a&gt;, loaded
pretty quickly, and started giving us wealth of knowledge to use was incredible.
My brain felt like fireworks were going off in it as I was thinking of all the
possibilities. At the same time, I also realized that JupyterLab isn&amp;rsquo;t
necessarily the ideal environment for maximum productivity. Users shared the
same environment, it didn&amp;rsquo;t have powerful extensions like VS Code, and it was
restricted in many ways.&lt;/p&gt;
&lt;p&gt;It was time to dig some tunnels.&lt;/p&gt;
&lt;h2&gt;The Cat&lt;/h2&gt;
&lt;p&gt;Visual Studio Code was our cat of choice. We primarily use it for Python, but it
also works well for Javascript development when we need to work on the frontend.
I started exploring remote development on VS Code back in 2021, I think, and at
that time, my goal was simply to write code on the go on my iPad, saving me the
hassle of carrying my laptop around (since I was already carrying my iPad
around).&lt;/p&gt;
&lt;h3&gt;Code Server&lt;/h3&gt;
&lt;p&gt;I started with &lt;a href="https://github.com/coder/code-server"&gt;Code Server&lt;/a&gt;, which is a project that aims to bring
VS Code to the browser. It was a bit annoying to setup (running it on Docker,
deploying it, connecting my stuff, security concerns, etc), but it worked well
enough. My biggest pain point by far, though, was the lack of extensions. I had
started using Github Copilot to write most of my code, as well as other
Microsoft extensions for Python development, and none of them were available on
Code Server.&lt;/p&gt;
&lt;p&gt;Another serious issue I had was syncing my projects across devices. I always had
to save my changes, push to git, pull from the other device, even though it was
just me working on the project. Soon enough, I was able to get access to VS Code
private beta of their remote development extension, aptly named &amp;ldquo;VSCode Server&amp;rdquo;.&lt;/p&gt;
&lt;h3&gt;VSCode Server&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/docs/remote/vscode-server"&gt;VSCode Server&lt;/a&gt; was a retaliatory move by Microsoft to counter
the success of Code Server (I speculate). It unlocked the full power of VS Code
along with all the extensions we know and love. It was also much easier to
setup, since it was just a VS Code extension. And yet, there was still a catch.&lt;/p&gt;
&lt;p&gt;You see, when I switched to VSCode Server, I needed a safe way to connect from
my iPad to whichever machine I was working on. Luckily, I stumbled upon
NordVPN&amp;rsquo;s new feature at the time, Meshnet. It was an additional feature that
made any device connected to NordVPN appear on the same network, as if they were
all connected to the same router. :mind-blown:&lt;/p&gt;
&lt;p&gt;If only it worked as reliably as it sounded.&lt;/p&gt;
&lt;p&gt;Sadly, after the initial euphoria, I realized that the connection was
unreliable, and I would often lose connection to the remote machine. After some
time, I gave up on it, and came to terms with the fact that I would have to
carry my laptop around with me.&lt;/p&gt;
&lt;h2&gt;Same Cat, Different Tunnel&lt;/h2&gt;
&lt;p&gt;Sorry for the unannounced segue regarding my previous attempts at remote
development outside work, but I felt it was necessary to set the stage for the
next part of this post.&lt;/p&gt;
&lt;p&gt;So, let&amp;rsquo;s get back to the A100 GPU and our local development needs.&lt;/p&gt;
&lt;h3&gt;Corn Kernels&lt;/h3&gt;
&lt;p&gt;Since we were already running JupyterLab on the VM, the immediate solution that
came to mind was to use JupyterLab&amp;rsquo;s VS Code extension to select a kernel
running on the VM, and use that to run our code. This worked seamlessly, and
honestly, I thought I as done then and there.&lt;/p&gt;
&lt;p&gt;However, we quickly realized that code referencing broke. VS Code showed
squiggly lines under all the imports, and we couldn&amp;rsquo;t navigate to the
definitions of any of the functions we were using. This was a deal breaker for
us.&lt;/p&gt;
&lt;p&gt;Another side effect was the lack of structure parity between the local project
and the actual environment. For example, if you want to import a local file, or
use an LLM, you need to reference it from the remote server, which made it very
awkward to work with.&lt;/p&gt;
&lt;h3&gt;Being a Good Host&lt;/h3&gt;
&lt;p&gt;At that point, I was like, no problem! We will just install Python 3 on the VM,
and use that as an SSH host similar to how we were using WSL2 on Windows
locally.&lt;/p&gt;
&lt;p&gt;Since we are using RHEL 7, it had python 2.7 installed by default. So, I fired
up &lt;a href="https://www.perplexity.ai/"&gt;perplexity&lt;/a&gt;, and it gave me a perfect, step-by-step guide on how
to install Python 3 from source. I had to do it this way, since yum was
outdated, and I didn&amp;rsquo;t want to risk downloading potentially incompatible
packages from other sources. The installation went fine, until I started the
REPL, and it turned out I now needed to install/compile openssl, sqlite, and a
bunch of other stuff. &lt;code&gt;(╯°□°）╯︵ ┻━┻&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;The Devil&amp;rsquo;s in the Container&lt;/h3&gt;
&lt;p&gt;Since we deploy all our services on Docker, it made sense to give Docker a shot
at this. I wanted to try using Dev Containers for a while, but never had a good
reason to do so. This was the perfect opportunity.&lt;/p&gt;
&lt;p&gt;I struggled for a bit at first, since the default dev container settings I had
was showing a warning as deprecated, while the new format didn&amp;rsquo;t yet have enough
documentation and examples online. I eventually figured it out, but it was just
for running a local container as a dev environment. I needed it on the GPU VM.&lt;/p&gt;
&lt;p&gt;I first tested the obvious way, which is to connect to the host through VS Code
SSH, then manage the dev containers. This kinda worked, but now you are in this
inception-like situation where you are connecting to a VM through SSH, to run a
container also on the remote host. Not a big fan.&lt;/p&gt;
&lt;p&gt;I then researched on how to use the &lt;code&gt;DOCKER_HOST&lt;/code&gt; environment variable to
connect the local docker client to a remote docker daemon. This had the
potential to eliminate the need for the SSH step, however, it introduced a new
more serious problem. When VS Code tries to prepare the dev container, it
symlinks the local project to a folder, which is then mounted to the container
as a volume. We can&amp;rsquo;t symlink the local project to the VM, obviously.&lt;/p&gt;
&lt;h3&gt;The Final Boss&lt;/h3&gt;
&lt;p&gt;As the weekend came around, I was thinking about what to try next, since it
seemed like such a simple problem! As I was thinking about the simple facts and
the problem I&amp;rsquo;m trying to solve here, I realized that I could just have a remote
container which the local VS Code can SSH into, just like WSL. I mean, just
because we will be running the code in a container, doesn&amp;rsquo;t mean we have to use
dev containers!&lt;/p&gt;
&lt;p&gt;This is the step we are at right now, honestly. Just setting up a simple
container that exposes an SSH server, and allows VS Code to connect to it
directly, without the need to go through the host first. An initial PoC showed
some promising results.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been reading Elon Musk&amp;rsquo;s biography, by Walter Isaacson, and I have to say,
it&amp;rsquo;s been a very inspiring read. I shall impart a prat of the book I found
particularly useful to apply at work:&lt;/p&gt;
&lt;p&gt;The Algorithm:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Question Every Requirement&lt;/li&gt;
&lt;li&gt;Delete as Much as Possible&lt;/li&gt;
&lt;li&gt;Simplify and Optimize&lt;/li&gt;
&lt;li&gt;Automate&lt;/li&gt;
&lt;li&gt;Accelerate&lt;/li&gt;
&lt;/ol&gt;</content><category term="python"></category></entry><entry><title>Appease Your AI</title><link href="https://mazyod.com/blog/2023/08/29/appease-your-ai/" rel="alternate"></link><published>2023-08-29T17:55:23+00:00</published><updated>2023-08-29T17:55:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2023-08-29:/blog/2023/08/29/appease-your-ai/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Who isn&amp;rsquo;t talking about AI these days? This topic has made its way into every
conversation, in every field, in every way imaginable (and unimaginable).&lt;/p&gt;
&lt;p&gt;The obvious areas where AI is mentioned could be automation, robotics, and
perhaps the hardware accelerator manufacturers. These areas are basically
intertwined with …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Who isn&amp;rsquo;t talking about AI these days? This topic has made its way into every
conversation, in every field, in every way imaginable (and unimaginable).&lt;/p&gt;
&lt;p&gt;The obvious areas where AI is mentioned could be automation, robotics, and
perhaps the hardware accelerator manufacturers. These areas are basically
intertwined with AI, no doubt about that.&lt;/p&gt;
&lt;p&gt;Then comes the second wave of areas, where AI &lt;em&gt;applications&lt;/em&gt; made sense, not
necessarily the underlying details. This ranges widely, from Software
Engineering, health care and wellness, education, all the way to weaponizing AI
at the military, scammers / bots, and other nefarious applications.&lt;/p&gt;
&lt;p&gt;Nowadays, you can bring up AI in &lt;em&gt;every conversation imaginable&lt;/em&gt;. Building a toy
for kids? Stick an AI in that and have it talk to your kids so you don&amp;rsquo;t have
to. How about making sandwiches? You got to pre-scan those ingredients with AI.
Also, have it optimize your menu over time to drive sales.&lt;/p&gt;
&lt;p&gt;Just to be clear, I am not saying AI is new, or it hasn&amp;rsquo;t touched our lives in
profound ways yet. It has, for decades now, even if most people are oblivious to
this fact. However, the surfacing of this topic and more ubiquitous applications
is what has changed recently.&lt;/p&gt;
&lt;h2&gt;So, Let&amp;rsquo;s Talk AI&lt;/h2&gt;
&lt;p&gt;Writing code alongside Github Copilot has influenced the way I write code. I
can&amp;rsquo;t tell for sure whether it&amp;rsquo;s good or bad in many cases, but it&amp;rsquo;s a bit scary
as probably millions of programmers out there are experiencing this affect as
well, as we all unknowingly converge because of the advent of code generating
LLMs.&lt;/p&gt;
&lt;h3&gt;Bad Copilot&lt;/h3&gt;
&lt;p&gt;When using Github Copilot for any reasonable amount of time, you will quickly
face an undeniable shortfall. It can only suggest code where the cursor is
pointing. I know, I know, you can use Github Copilot Chat / ChatGPT / &amp;hellip; etc to
sort of work around this, but that really breaks your flow. I like writing code
in small chunks, and would expect Copilot to mimic the way I write code, namely,
but moving the cursor and making changes in several places to achieve the
desired result.&lt;/p&gt;
&lt;p&gt;Instead, we get this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run_some_code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
  &lt;span class="n"&gt;some_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;FOO_BAR&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;output_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;file.txt&amp;quot;&lt;/span&gt;

  &lt;span class="c1"&gt;# check if the file exists&lt;/span&gt;
  &lt;span class="c1"&gt;# if os.path.exists(...)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Copilot will invariably use the available imports to deduce that you probably
want to use them as oppose to other, potentially better, approaches. In this
case, I usually stick to using &lt;code&gt;pathlib.Path&lt;/code&gt;. Honestly, I&amp;rsquo;ve avoided &lt;code&gt;pathlib&lt;/code&gt;
perhaps once in my career due to performance concerns, but in all other cases,
the ergonomics beats &lt;code&gt;os.path&lt;/code&gt; 10-0.&lt;/p&gt;
&lt;p&gt;Another issue that may arise is the lack of proper type hints. Since we only
import &lt;code&gt;Any&lt;/code&gt; from &lt;code&gt;typing&lt;/code&gt; module, Copilot will use &lt;code&gt;Any&lt;/code&gt; and built-ins
exclusively to annotate your code (99% of the time). Many cases where I wanted
it to use &lt;code&gt;Callable&lt;/code&gt; it would just use &lt;code&gt;callable&lt;/code&gt; built-in instead, for example.&lt;/p&gt;
&lt;h3&gt;Good Pilot&lt;/h3&gt;
&lt;p&gt;I actually started to change the way I write code in order to make copilot more
capable and expressive, so to speak. Here is one obvious improvement over the
above:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;dataclasses&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;dc&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;datetime&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;dt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;typing&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;t&lt;/span&gt;

&lt;span class="nd"&gt;@dc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dataclass&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;datetime&lt;/span&gt;
  &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Callable&lt;/span&gt;&lt;span class="p"&gt;[[],&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By importing the modules themselves (and using aliases to reduce verbosity), we
have effectively prepared the environment for Copilot to be able to work more
efficiently, making me the copilot, effectively!&lt;/p&gt;
&lt;p&gt;This is a very simple change that anyone can adopt to their code style, and
would pay back dividends in time saved trying to steer Copilot to use certain
imports.&lt;/p&gt;
&lt;h2&gt;First of Many&lt;/h2&gt;
&lt;p&gt;This is just one very obvious impact using Copilot has had over my code style,
while I am sure many less obvious have already made their way in. Personally, I
am embracing it as a good thing. At the end of the day, code is not really art.
It is instructions arranged in specific ways to serve a higher purpose, not
more.&lt;/p&gt;
&lt;p&gt;I keep trying to think of other possibilities to better leverage Github Copilot.
A perhaps extreme example would be to force myself to document each function
with a Copilot-friendly docstring that should produce the desired result + unit
test without any intervention from me besides iterating on the docstring.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Whenever you feel useless in the face of AI&amp;rsquo;s quasi-infinite potential&amp;hellip;
Whenever you see yourself unable to cope with AI&amp;rsquo;s lighting-fast advancements&amp;hellip;
Whenever you want to just shut all this out and live in simpler times&amp;hellip;&lt;/p&gt;
&lt;p&gt;Remember&amp;hellip;&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s already here, and there is no stopping it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="AI Overlord" src="/images/super-ai.png"&gt;&lt;/p&gt;</content><category term="python"></category></entry><entry><title>Verdict: It's a Match!</title><link href="https://mazyod.com/blog/2023/08/20/verdict-its-a-match/" rel="alternate"></link><published>2023-08-20T16:55:23+00:00</published><updated>2023-08-20T16:55:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2023-08-20:/blog/2023/08/20/verdict-its-a-match/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Second blog post since forever, and I have no idea what this one should be
about. The main problem is I&amp;rdquo;m writing this a I finish my workout, so I don&amp;rsquo;t
have much going on in terms of setup, but that&amp;rsquo;s fine.&lt;/p&gt;
&lt;p&gt;After the rant in …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Second blog post since forever, and I have no idea what this one should be
about. The main problem is I&amp;rdquo;m writing this a I finish my workout, so I don&amp;rsquo;t
have much going on in terms of setup, but that&amp;rsquo;s fine.&lt;/p&gt;
&lt;p&gt;After the rant in the last post, I would like to aim for a more informative post
this time. Something with more &amp;ldquo;meat&amp;rdquo;, so to speak. It&amp;rsquo;s not much, but perhaps
I&amp;rsquo;ll share my experience using Python&amp;rsquo;s &lt;code&gt;match&lt;/code&gt; statement; introduced in Python
3.10.&lt;/p&gt;
&lt;h2&gt;The Primal Age&lt;/h2&gt;
&lt;p&gt;In a not so distant past, writing code for checking the structure and types of
objects was a huge pain in Python. Here is a real-world example of an object
schema:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;job_type&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;training&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;train_config&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;some config&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;&amp;quot;min_examples&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&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;Intuitively, &lt;code&gt;job_type&lt;/code&gt; value can be one of several predefined values, and based
on the &lt;code&gt;job_type&lt;/code&gt;, we would like to invoke a custom flow, or banch of code if
you will. How would one normally handle this in Python?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handle_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;job_type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;job_type&amp;quot;&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;job_type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;training&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;train_job&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;job&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Looks fine to me, what do you think?&lt;/p&gt;
&lt;p&gt;The main concern that screams danger at me is the full trust we have that the
job is indeed a dict and that is has the key &lt;code&gt;job_type&lt;/code&gt;. Granted, fixing the
potential &lt;code&gt;KeyError&lt;/code&gt; is easy, just add a default and you&amp;rsquo;re golden. Regarding
the type assurance, you have to have some level of trust, especially if this is
an internal function that you fully own.&lt;/p&gt;
&lt;p&gt;This code is actually perfectly fine, and I wouldn&amp;rsquo;t necessary bark at it during
a code review.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s take another, rather similar example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# snippet from a function that takes an SQLAlchemy orm type and a &amp;quot;dynamic filter&amp;quot;,&lt;/span&gt;
&lt;span class="c1"&gt;# and returns a SQLAlchemy filter expression.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# e.g.&lt;/span&gt;
&lt;span class="c1"&gt;# (&amp;quot;date&amp;quot;, (&amp;quot;2022-01-01&amp;quot;, &amp;quot;2023-01-01&amp;quot;)) -&amp;gt; orm_type.date.between(date1, date2)&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orm_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filter_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to go ahead and gouge your eyeballs out, please, be my guest. I
started this project when my dependencies required me to use Python 3.8, and
then soon after Python 3.9. I remember how badly I wanted to &amp;ldquo;matchify&amp;rdquo; this
code&amp;hellip;&lt;/p&gt;
&lt;p&gt;I mean, even if one is more inclined to make it self-documenting, it may look
something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
  &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;is_between_expr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filter_&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;list&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;isbetween_expr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filter_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yikes, doesn&amp;rsquo;t look any better to me, honestly.&lt;/p&gt;
&lt;h2&gt;Eye Candy&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orm_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;between&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;value&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;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;^%[^%]+%$&amp;quot;&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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orm_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;like&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="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;key&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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orm_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;_&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;op&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;operator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;op&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;getattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orm_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&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="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;filter_&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Huge sigh of relief! Not only is the code succinct, safe, expressive it&amp;rsquo;s also
self-documenting. Keep in mind this code is deep within the code base, after
Pydantic has done its validation on the input, so no need for us to be pedantic
about it (pun intended). Yet we really do need to check types and structure to
properly determine what to execute.&lt;/p&gt;
&lt;p&gt;I can hear you already from shouting from behind the screen:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;&lt;em&gt;Actually&lt;/em&gt;, the problem here is the spec itself. It&amp;rsquo;s too vague.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Fair enough. If we had passed the actual operation as some sort of &lt;code&gt;OP_CODE&lt;/code&gt;
type of thing, parsing would definitely be less hairy. To be completely honest,
this code is not used anymore, lol. But for that time when I needed to quickly
have a simple spec to manage sql filters dynamically, &lt;code&gt;match&lt;/code&gt; had my back.&lt;/p&gt;
&lt;h2&gt;Match Madness&lt;/h2&gt;
&lt;p&gt;For the final piece of this post, I present you with an actually useful use case
for the &lt;code&gt;match&lt;/code&gt; statement:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# Recursively parse an SQLAlchemy ORM type, mapping everything to primitive types.&lt;/span&gt;
&lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_to_dict_or_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exclude_refs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;_to_dict_or_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exclude_refs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;isinstance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;startswith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;_&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sa&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;_fields&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;_to_dict_or_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exclude_refs&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="n"&gt;_to_dict_or_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exclude_refs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;_fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;# noqa&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_to_dict_or_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exclude_refs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Enum&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;_&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;copy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;deepcopy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Honestly, this looks like a monster. The value of this code will also greatly
diminish once we migrate to SQLAlchemy 2.0 with &lt;code&gt;Mapped&lt;/code&gt; attributes, but the
main use-case still holds true.&lt;/p&gt;
&lt;p&gt;The idea is that working with arbitrary data structures, with various shapes and
sizes, can get out of hand very quickly. Being able to break down the conditions
that need to be met into readable statements goes a long way. This code could
use a bit of cleaning as well, perhaps using local functions to keep each &lt;code&gt;case&lt;/code&gt;
body as simple as possible, so there is still room to improve beyond just using
&lt;code&gt;match&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I am all for Python&amp;rsquo;s steady march towards the functional paradigm. The less
side-effects, mutation, inheritance, and other monsters you can avoid, the
better off we&amp;rsquo;ll all be. I just wish pipes come very soon. They just can&amp;rsquo;t come
soon enough, that&amp;rsquo;s for sure.&lt;/p&gt;</content><category term="python"></category></entry><entry><title>Playing the Part</title><link href="https://mazyod.com/blog/2023/08/19/playing-the-part/" rel="alternate"></link><published>2023-08-19T12:55:23+00:00</published><updated>2023-08-19T12:55:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2023-08-19:/blog/2023/08/19/playing-the-part/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Boy, has it been ages since I last wrote a post. I can hardly recall my style,
even, however that&amp;rsquo;s not really an issue as we&amp;rsquo;ll see.&lt;/p&gt;
&lt;h2&gt;Out With the Old&lt;/h2&gt;
&lt;p&gt;As you may (or may not) have noticed, the blog is finally migrated to a sensible …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Boy, has it been ages since I last wrote a post. I can hardly recall my style,
even, however that&amp;rsquo;s not really an issue as we&amp;rsquo;ll see.&lt;/p&gt;
&lt;h2&gt;Out With the Old&lt;/h2&gt;
&lt;p&gt;As you may (or may not) have noticed, the blog is finally migrated to a sensible
static site generator, namely &lt;a href="https://getpelican.com"&gt;Pelican&lt;/a&gt;. I&amp;rsquo;ve been using
Jekyll for over a decade! Albeit a decade of frustration, unfortunately.&lt;/p&gt;
&lt;p&gt;Look, I am not one to complain, especially when it comes to open source
software. As an open source contributor myself, I know how hard it is to
maintain a project, let alone a popular one. However, at the end of the day, you
have to be entitled to your own opinion, and sharing that opinion will help
others navigate the open source landscape better.&lt;/p&gt;
&lt;p&gt;So, what&amp;rsquo;s wrong with Jekyll?&lt;/p&gt;
&lt;h3&gt;The Downsides&lt;/h3&gt;
&lt;p&gt;First and foremost, Ruby.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve played around with Ruby in the past, and my experience was generally pretty
pleasant. I&amp;rsquo;m a big fan of Elixir, for that matter, and its syntax is heavily
inspired by Ruby. Heck, half of the Elixir core developers are recovering
Rubyists. Not only that, but I&amp;rsquo;ve also used Ruby with respect to iOS development
with projects like Cocoapods and Fastlane.&lt;/p&gt;
&lt;p&gt;Alas, I&amp;rsquo;ve &lt;strong&gt;never&lt;/strong&gt; really truly understood Ruby tooling. There is the rake
thing, then there is the Gem thing, and then there is the Bundler thing. Every
single time I came back to my blog in a new environment, I had to struggle with
these tools. I mean, don&amp;rsquo;t get me wrong, I don&amp;rsquo;t mind playing with a new
language for fun. I&amp;rsquo;ve written small projects with Go and Rust, but the tooling
they provide is phenomenal.&lt;/p&gt;
&lt;p&gt;Next up, Jekyll itself (obviously).&lt;/p&gt;
&lt;p&gt;As far as I can tell, ever since Github adopted (acquired?) Jekyll, development
of the framework slowed down tremendously. For a static site generator, keeping
with the times is crucial, to say the least. Even if the framework wants to be
minimalistic, constant refactoring and simplification for reduced complexity and
easier onboarding is paramount. I mean, Jekyll was so unapproachable to many in
the past, to the point that it lead to the development of
&lt;a href="http://octopress.org"&gt;Octopress&lt;/a&gt;. &lt;em&gt;(Granted, Jekyll eventually got a bit better
over time and the need for Octopress greatly diminished after that)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Other issues I had with Jekyll were mostly inconveniences rather than
deal-breakers, however, you know how a thousand paper cuts &lt;em&gt;can&lt;/em&gt; kill you. These
range from the performance of Jekyll itself, to the insane number of
dependencies, some of which are just a pain to fetch/build (I&amp;rsquo;m looking at you,
nokogiri), and the lack of in-depth documentation. &lt;em&gt;(Just to make sure, I opened
the Jekyll website to see if it was improved, and sure enough, it&amp;rsquo;s the same
website from a decade ago!)&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;In With the New&lt;/h2&gt;
&lt;p&gt;Enter &lt;a href="https://gohugo.io"&gt;Hugo&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;Yes, you heard that right, I migrated to Hugo. The dazzling hotness of Go, in
combination with the clean website/docs of the framework, made me jump in head
over heels. And let me tell you, it was super exciting! At first anyway.&lt;/p&gt;
&lt;p&gt;Migrating to Hugo was generally a pleasant experience. They had importers that
support importing a site from Jekyll, so that took a huge burden off my plate.
Next, I was just astonished by the performance. The whole site was being fully
generated in mere &lt;em&gt;milliseconds&lt;/em&gt; every time I made a change. I was in love&amp;hellip;
Until.&lt;/p&gt;
&lt;p&gt;Sadly, the honeymoon phase was over within mere days. I don&amp;rsquo;t even recall
exactly what went wrong, to be honest. It was just too hard for me to work with,
constantly looking up documentation, spending time trying to figure out what are
the supported functions in the template engine, and so on&amp;hellip; For example, in
order to format the date object, I was searching for the date specifiers for Go,
and to my astonishment, &lt;a href="https://gosamples.dev/date-time-format-cheatsheet/"&gt;they use an &lt;strong&gt;actual&lt;/strong&gt; date for
formatting&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This gave me an immediate lightbulb moment. What if I used a static site
generator built with a language that I know and love?&lt;/p&gt;
&lt;h2&gt;In With the Newer&lt;/h2&gt;
&lt;p&gt;Enter &lt;a href="https://getpelican.com"&gt;Pelican&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;I have to say, when I was first exploring Pelican, I was extremely hesitant to
throw away the efforts I spent on the Hugo blog migration. Pelican uses
reStructured text as the default format, which rubbed me the wrong way as a
first impression&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Start tangent&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Speaking of rubbed the wrong way, it is actually the exact same feeling when I
first learned about &lt;a href="https://peps.python.org/pep-0518/"&gt;pyproject.toml&lt;/a&gt;. I&amp;rsquo;ve been using Python for years,
and all of a sudden, there is this new markup language I&amp;rsquo;ve never used before,
&lt;a href="https://en.wikipedia.org/wiki/TOML"&gt;with a rather silly name, too&lt;/a&gt;, and I&amp;rsquo;m suppose to adopt it
to manage my dependencies and project? The inner resistance was very high at
first, but as is always the case, I had trust in the seasoned developers of the
PSF, and decided to lower my guard and approach it with an open-mind. Few years
later, this is perhaps the cleanest, flat-structure markup language I&amp;rsquo;ve worked
with.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;End tangent&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Pelican also didn&amp;rsquo;t use &lt;a href="https://frontmatter.codes/docs/markdown"&gt;frontmatter&lt;/a&gt;, like Jekyll and Hugo.
Finally, I was having trouble with the bare-bones, minimalistic core that
Pelican aims to be. It felt like I&amp;rsquo;ll be spending most of my time hunting for
plugins to make my workflow work. Thankfully, I was wrong.&lt;/p&gt;
&lt;h2&gt;Great Artists&lt;/h2&gt;
&lt;p&gt;After getting past the initial learning curve of Pelican, which mostly consisted
of figuring out the structure and settings (like what are themes, how are static
files added, what is the best configuration for development vs. publishing,
&amp;hellip;etc), I realized that I could just search Github for other Pelican-ians (?)
to see what their set up looked like and if I can, ehm, &amp;ldquo;borrow&amp;rdquo; some of their
knowledge. Surely enough, found the indispensible
&lt;a href="https://facelessuser.github.io/pymdown-extensions/"&gt;pymdown-extensions&lt;/a&gt;. Basically, pymdown-extensions is to
Python markdown project, as oh-my-zsh is to the Zsh project.&lt;/p&gt;
&lt;p&gt;Armed with these fantastic extensions, the migration progress pace started to
pick up. I spent &lt;em&gt;way&lt;/em&gt; more time than I should polishing the code blocks, and
trying out different themes and styles for that matter. Code blocks have been an
obsession that I haven&amp;rsquo;t been able to crack before. I&amp;rsquo;ve tried to embed Github
gists, different highlight frameworks, both in Javascript and pre-rendered, but
was never really satisfied by the outcome. That is, until now.&lt;/p&gt;
&lt;h2&gt;Closing the Loop&lt;/h2&gt;
&lt;p&gt;Remember that remark in the introduction? About how not remembering my style is
not really an issue? Well that&amp;rsquo;s because of the following&amp;hellip;&lt;/p&gt;
&lt;p&gt;At the beginning of the migration, I was going to import all the Sass and HTML
templates setup from the old site. I wanted to finish this migration as fast as
possible, but quickly realized a few main points:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;There was &lt;strong&gt;A LOT&lt;/strong&gt; of unused crap laying around that I never really bothered
   to clean up in the past. Most of it was because of using a Jekyll theme as a
   base, and then heavily modified it to the point that I was probably using
   only 10% of the original theme.&lt;/li&gt;
&lt;li&gt;I may not look like it, but I am a web developer now. Indeed, in the past 3
   years, I&amp;rsquo;ve engrossed myself in web development and I&amp;rsquo;ve become much more
   familiar with aspects of web development than before. I could easily see the
   many issues that existed, and how to quickly fix them.&lt;/li&gt;
&lt;li&gt;Many of the assumptions I had around the structure of the blog and layout
   were simply wrong, and I was gonna port all that to this new, fresh beginning
   without a second thought. Alternatively, I could take it piece by piece and
   evaluate what stays and what goes.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hence, I shall not simply keep carrying the baggage of the past for the mere
legacy of it. It shall be re-evaluated and, if needed, improved upon &amp;hellip; for a
better future(?).&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m wondering, as I always do, is this post a one-off, or is it a proper reboot
of this forgotten blog? It pains me to see the missing years in the home index,
as well as the existence of just a handful of posts in some years&amp;hellip; But this
pain is but a motivator &amp;hellip; for a better future. (Maybe I should try openai
whisper to blog with just voice. That will be interesting.)&lt;/p&gt;</content><category term="rant"></category></entry><entry><title>Async Pipes</title><link href="https://mazyod.com/blog/2022/03/10/async-pipes/" rel="alternate"></link><published>2022-03-10T03:55:23+00:00</published><updated>2022-03-10T03:55:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2022-03-10:/blog/2022/03/10/async-pipes/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Over the past couple of posts, I explored basic parallelism in Python with the help of Ray. Since then, I&amp;rsquo;ve adopted the library in my work and built some pretty cool things with it, all of which I would like to cover in detail someday:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Actor Pools&lt;/em&gt;: I …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Over the past couple of posts, I explored basic parallelism in Python with the help of Ray. Since then, I&amp;rsquo;ve adopted the library in my work and built some pretty cool things with it, all of which I would like to cover in detail someday:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Actor Pools&lt;/em&gt;: I&amp;rsquo;ve touched on the topic briefly in the last post.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Worker Queues&lt;/em&gt;: Implementing a robust queue with progress updates around Ray workers.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Async Pipeline&lt;/em&gt;: Implementing a flexible, reusable data processing pipeline with Ray.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since I would like to cover the Async Pipelines in this post, let&amp;rsquo;s see what they&amp;rsquo;re all about, shall we?&lt;/p&gt;
&lt;h2&gt;The Shrinking Middle Class&lt;/h2&gt;
&lt;p&gt;Before we can talk about async pipelines, we must first talk about the shrinking Middle Class.&lt;/p&gt;
&lt;p&gt;I follow U.S. politics simply because it&amp;rsquo;s interesting to me. You could say it&amp;rsquo;s the same reason I watch shows on Netflix, or browse YouTube for Mario speedruns. One key topic that keeps being brought in U.S. politics up is the problem of &amp;ldquo;The Shrinking Middle Class&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Given the existence of a Middle Class, this means that there is also an Upper Class and a Lower Class. The Upper Class are your CEOs, Investors, and Leaders of the nation. Although they are a small percentage, but effectively they are responsible for most of the &lt;strong&gt;jobs&lt;/strong&gt; in the country.&lt;/p&gt;
&lt;p&gt;The Lower Class, on the other hand, are your student-debt ridden youth and immigrants who are left to pick up the slack, doing meaningless jobs that no one else wants to do.&lt;/p&gt;
&lt;p&gt;So, what is the problem if the Middle Class is shrinking?&lt;/p&gt;
&lt;p&gt;Well, people in the Lower Class might lose hope of one day reaching the Middle Class, given its inevitable demise. The people of the Upper Class won&amp;rsquo;t have people doing the interesting work for them, slowing down innovation and economical growth.&lt;/p&gt;
&lt;p&gt;I know what you&amp;rsquo;re thinking right about now. How on earth is this remotely relevant to the topic of this post?&lt;/p&gt;
&lt;p&gt;Glad you asked.&lt;/p&gt;
&lt;h2&gt;Scaling the Middle Class&lt;/h2&gt;
&lt;p&gt;Aside from my need for parallelism in Python to simply scale a worker pool that handles API requests, I also needed that same pool to process work within a data pipeline.&lt;/p&gt;
&lt;p&gt;The data pipelines I have usually involves one (or a few) data generators that are simply Python generators that generate data for processing. (Say, &lt;em&gt;generate&lt;/em&gt;, one more time&amp;hellip;)&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s your Upper Class.&lt;/p&gt;
&lt;p&gt;Data is then consumed by workers that perform some &lt;em&gt;interesting&lt;/em&gt; processing, generating a result. This processing is where the bulk of the CPU cycles go to.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s your Middle Class.&lt;/p&gt;
&lt;p&gt;Finally, a collector collects the results and commits them to a database, taking care of any data inconsistencies and reporting the results at the end.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s your Lower Class.&lt;/p&gt;
&lt;p&gt;And hence, our goal today is to scale the Middle Class only, in order to process as much data as possible, maximizing CPU utilization (productivity) along the way.&lt;/p&gt;
&lt;h2&gt;Fan-out &amp;amp; Fan-in&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s try our hands on a basic approach to tackle the problem statement above, shall we?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;concurrent.futures&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;work&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;done&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;ThreadPoolExecutor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data_generator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;future&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;future&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_done_callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is fine &amp;hellip; except, the whole place is on fire, and I&amp;rsquo;m too busy supressing the cringe to care. Let&amp;rsquo;s ignore the fact that we are using threads here, because that part is just for demonstration purposes.&lt;/p&gt;
&lt;p&gt;My issue with this code is the nesting and lack of clarity. I also believe the &lt;code&gt;data_generator&lt;/code&gt; will fill up the executor as fast as it possibly can, which can lead to memory growth. Back-pressure to limit the data generator output would be nice, too. This problem also makes it harder to track our progress of how much data was processed.&lt;/p&gt;
&lt;p&gt;Finally, we are in an era of &lt;code&gt;async&lt;/code&gt; / &lt;code&gt;await&lt;/code&gt;. I don&amp;rsquo;t even want to try throwing that into the mix, in fear of reaching depths for which there is no escape.&lt;/p&gt;
&lt;p&gt;(&lt;em&gt;DISCLAIMER&lt;/em&gt;: I have to admit though, I didn&amp;rsquo;t expect to come up with a palatable solution on the fly for this problem, lol. I spent way too much time solving it in our project)&lt;/p&gt;
&lt;h2&gt;I Hereby Declare&lt;/h2&gt;
&lt;p&gt;&amp;hellip; the scalability of the Middle Class!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;async_flow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;async_flow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_generator&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;async_flow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;work&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;async_flow&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Layer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;callback&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;&lt;code&gt;async_flow&lt;/code&gt; is the basic utility I prepared in order to reuse the scalability semantics across the project. The details of the utility is too much to cover in this post, but it basically has two types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Layer&lt;/code&gt;: Declaring a function, optionally scaling it as needed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pipeline&lt;/code&gt;: To declare your &lt;code&gt;Layer&lt;/code&gt;s in for execution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not only is it a pleasure to just look at, but it also supports back-pressure, because the &lt;code&gt;Layer&lt;/code&gt; objects passed in are stitched togething using &lt;code&gt;asyncio.Queue&lt;/code&gt;. This way, if the &lt;code&gt;work&lt;/code&gt; &lt;code&gt;Queue&lt;/code&gt; object is full, for example, the &lt;code&gt;data_generator&lt;/code&gt; will patiently block on the &lt;code&gt;await queue.put(data)&lt;/code&gt; statement till it&amp;rsquo;s free.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Although I meant to cover a little more details about &lt;code&gt;async_flow&lt;/code&gt;, or at least give a full working example for that matter, I spend too much time on the introduction and now it&amp;rsquo;s getting late. Regardless, the internals are worthy of a whole post on it&amp;rsquo;s own.&lt;/p&gt;</content><category term="programming"></category></entry><entry><title>Balance</title><link href="https://mazyod.com/blog/2022/01/19/balance/" rel="alternate"></link><published>2022-01-19T20:30:23+00:00</published><updated>2022-01-19T20:30:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2022-01-19:/blog/2022/01/19/balance/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the previous post, I wrote about parallelism, and towards the end, mentioned Ray, the ultimate python package for parallelism.&lt;/p&gt;
&lt;p&gt;I played around with it today, and wanted to give my take as well as describe the new challenge that I am currently stuck on.&lt;/p&gt;
&lt;h2&gt;Prelude&lt;/h2&gt;
&lt;p&gt;Ray is just …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the previous post, I wrote about parallelism, and towards the end, mentioned Ray, the ultimate python package for parallelism.&lt;/p&gt;
&lt;p&gt;I played around with it today, and wanted to give my take as well as describe the new challenge that I am currently stuck on.&lt;/p&gt;
&lt;h2&gt;Prelude&lt;/h2&gt;
&lt;p&gt;Ray is just so much fun. I am so glad I found it.&lt;/p&gt;
&lt;p&gt;Want to define a function that can execute in the background?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@ray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just how sick is this? Seriously? That function could also execute in a distributed manner, on some other machine entirely if you wanted to.&lt;/p&gt;
&lt;p&gt;How about Actors? That must be more challenging to write, right? &amp;hellip; WRONG.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nd"&gt;@ray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Actor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;

&lt;span class="n"&gt;actor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Actor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="c1"&gt;# Output: 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Sateful actors, with a few simple lines of code. Just love it.&lt;/p&gt;
&lt;h2&gt;The Catch&lt;/h2&gt;
&lt;p&gt;So far, so good. Where is the catch?&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t been able to find a built-in approach to dispatch work to a pool of workers and await each result separately.&lt;/p&gt;
&lt;p&gt;I mean, there is &lt;code&gt;ray.util.ActorPool&lt;/code&gt;, however, its API is very limited. As far as I can tell, the main APIs are &lt;code&gt;ActorPool.map&lt;/code&gt; and &lt;code&gt;ActorPool.submit&lt;/code&gt;. &lt;code&gt;ActorPool.map&lt;/code&gt; makes sense if you have a bunch of data to process, but &lt;code&gt;ActorPool.submit&lt;/code&gt; is more for one-off tasks.&lt;/p&gt;
&lt;p&gt;Given the above, &lt;code&gt;ActorPool.map&lt;/code&gt; definitely won&amp;rsquo;t do for my usecase which involves submitting work that is coming from an API request. &lt;code&gt;ActorPool.submit&lt;/code&gt; sounded interesting, however, I have no idea why they chose to make it not return anything. That means, once you submit a task, you have to go search somewhere else for the result :ugh:.&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;I will now try to conjure up a solution as I go.&lt;/p&gt;
&lt;p&gt;At first, I noticed that &lt;code&gt;ActorPool&lt;/code&gt; had one more cool API up its sleeve. &lt;code&gt;ActorPool.pop_idle&lt;/code&gt;. That would work for me, if I can just try to pop an idle actor, do my work on it, and return the result. Unfortunately, if there isn&amp;rsquo;t an idle actor at the time of the call, it will return &lt;code&gt;None&lt;/code&gt;. I wanted a blocking solution instead.&lt;/p&gt;
&lt;p&gt;After reading the source for &lt;code&gt;ActorPool&lt;/code&gt;, I realized the usecase I want to use the actors for is completely different. For example, I would like to keep the &lt;code&gt;async&lt;/code&gt; api.&lt;/p&gt;
&lt;p&gt;&amp;hellip; After a bit of pondering, I realized I could just use a blocking queue to achieve the desired result. Pop an available actor, use it, then put it back. New API requests that come in will block until an actor is available in the queue.&lt;/p&gt;
&lt;p&gt;Of course, I will prepare my own abstraction around the queue of actors to provide a simple API similar to &lt;code&gt;ActorPool&lt;/code&gt;, &lt;code&gt;ProcessPoolExecutor&lt;/code&gt;, etc.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;How far will this streak go?&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Not Fast Enough</title><link href="https://mazyod.com/blog/2022/01/18/not-fast-enough/" rel="alternate"></link><published>2022-01-18T20:30:23+00:00</published><updated>2022-01-18T20:30:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2022-01-18:/blog/2022/01/18/not-fast-enough/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Why am I writing after such a long absence? Wrong question. Why &lt;em&gt;haven&amp;rsquo;t&lt;/em&gt; I been writing for so long?!&lt;/p&gt;
&lt;p&gt;I could just sit here and give all kinds of excuses and reasons as to why that is, but the truth is &amp;hellip; I slipped. I think.&lt;/p&gt;
&lt;p&gt;Programming was pretty …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Why am I writing after such a long absence? Wrong question. Why &lt;em&gt;haven&amp;rsquo;t&lt;/em&gt; I been writing for so long?!&lt;/p&gt;
&lt;p&gt;I could just sit here and give all kinds of excuses and reasons as to why that is, but the truth is &amp;hellip; I slipped. I think.&lt;/p&gt;
&lt;p&gt;Programming was pretty much my life back in the day. I was writing code and learning on such a constant pace, it only made sense to keep writing these blog posts as a way to channel the residual energy. Not so much now.&lt;/p&gt;
&lt;p&gt;Not the time to cover this, it&amp;rsquo;s time to get my time&amp;rsquo;s worth in reviving this zombie of a blog!!&lt;/p&gt;
&lt;h2&gt;The Mourning&lt;/h2&gt;
&lt;p&gt;As previously expressed, emphasized, and then over-emphasized, Elixir is the dream language for me. I wouldn&amp;rsquo;t waste time nor effort on other programming languages if I had the choice, alas, life ain&amp;rsquo;t that rosy.&lt;/p&gt;
&lt;p&gt;In my current project, I have to settle with Python, which would be my second best choice&amp;hellip; Although that might change given the introduction of the Actor pattern in Swift. Back to the point.&lt;/p&gt;
&lt;p&gt;Python is a very productive language, generally speaking. There is not much worry about in terms of syntax, however, other quite critical things are missing. Paralellism.&lt;/p&gt;
&lt;h2&gt;The Multiverse&lt;/h2&gt;
&lt;p&gt;In python, you could try and make your code &amp;ldquo;parallel&amp;rdquo; by using threads or asyncio, but you shall not achieve much success. Threads are haunted by the all-evil GIL, which is a global interpreter lock. It won&amp;rsquo;t actually allow mutiple threads to run at the same time, and it will also block the main thread from doing anything else.&lt;/p&gt;
&lt;p&gt;As for asyncio, it is single-threaded by definition, so it is not a parallelism tool. It is, however, useful for concurrency. That leaves us with the only remaining viable option, that is multiprocessing.&lt;/p&gt;
&lt;h2&gt;The Future&lt;/h2&gt;
&lt;p&gt;Hello, this is Maz from the future! Maz from 15 minutes ago wrote the post up till now, and he already made a mistake!&lt;/p&gt;
&lt;p&gt;Multiprocessing is indeed an option, but not the only remaining option. You could do distributed computing, just as an example. Actually, after I wrote the last line about multiprocessing above, I thought to myself how the multiprocessing module is extremely limited!&lt;/p&gt;
&lt;p&gt;You can&amp;rsquo;t really send local funtions/classes, as the pickling process to send the information to the subprocesses uses pickle, which only sends a reference. Dill, however, is a third-party module that allows you to send local objects. Instead of using dill on top of multiprocessing, however, might as well find a all-in-one solution that replaces multiprocessing usage altogether.&lt;/p&gt;
&lt;p&gt;Just to mention another annoying limitation of the multiprocessing module, it doesn&amp;rsquo;t allow spawining nested multiprocessing pools. This is because the multiprocessing pool creates daemon processes, which aren&amp;rsquo;t allowed to have children.&lt;/p&gt;
&lt;h2&gt;Follow the Light (Ray)&lt;/h2&gt;
&lt;p&gt;Ray is a python package that promises to keep things simple, while still being able to do some pretty cool things. Right off the bat, they seem to have the actor pattern as a feature. Besides that, they allow you to structure your code declaratively in order to make it executable in a parallel environment. After that, it&amp;rsquo;s totally up to you how you want to parallelize the execution. You could use threads, processes, or even distributed systems.&lt;/p&gt;
&lt;p&gt;Gotta hand it to them, I am sold.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I had to clear my head, lay out everything on the table, hence I decided to write again. This was extremely helpful in articulating my thoughts and reaching a conclusion on what I should do about this parallelism problem. Perhaps I should do this more often.&lt;/p&gt;
&lt;p&gt;I leave you with a nice quote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The best way to predict the future is to invent it.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Umm, no &amp;hellip; The above quote was actually predicted by github copilot. I wanted to write a different one:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;If this were easy, how would it look like?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&amp;ndash; &lt;cite&gt;Tim Ferriss&lt;/cite&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="programming"></category></entry><entry><title>A Quick Abstraction</title><link href="https://mazyod.com/blog/2018/11/02/a-quick-abstraction/" rel="alternate"></link><published>2018-11-02T22:30:23+00:00</published><updated>2018-11-02T22:30:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-11-02:/blog/2018/11/02/a-quick-abstraction/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As software engineers, our job is to make sure computers behave in very specific ways when the software we have built is being executed. Now, this sounds extremely trivial, but this is what it really boils down to&amp;hellip;&lt;/p&gt;
&lt;p&gt;Unfortunately, the tools we are provided to make this happen are …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As software engineers, our job is to make sure computers behave in very specific ways when the software we have built is being executed. Now, this sounds extremely trivial, but this is what it really boils down to&amp;hellip;&lt;/p&gt;
&lt;p&gt;Unfortunately, the tools we are provided to make this happen are extremely flawed and rudimentary. Even if I&amp;rsquo;m passionate about software and programming, building software shouldn&amp;rsquo;t be so hard. But it is, and we end up making tens, if not hundreds, of micro-decisions when writing software..&lt;/p&gt;
&lt;p&gt;Perhaps the noblest of all goals a software engineer could ever cherish is fighting complexity. Less complexity leads to so many wonderful things, some of which are less chances for error, easier maintenance, and many times, less code overall.&lt;/p&gt;
&lt;p&gt;An important weapon against complexity is abstraction. If done right, a proper abstraction could help you break down a very complicated problem into it&amp;rsquo;s essential parts, and make it much more manageable when looking at it as a whole. I wanted to demonstrate one example of that today.&lt;/p&gt;
&lt;h2&gt;Perform Once&lt;/h2&gt;
&lt;p&gt;Here is an exercise for you, dear reader. Say we have some class, and within that class, we have some code we want to execute only once during the whole life of its object. How would we achieve that?&lt;/p&gt;
&lt;p&gt;&amp;hellip; Think about it for a bit.&lt;/p&gt;
&lt;p&gt;Well, the answer here should be relatively easy and simple. Put that code in the constructor of that object. Done. The constructor is guaranteed (by the compiler) to be executed only once. Not bad, so, let&amp;rsquo;s throw in an extra piece of the requirement.&lt;/p&gt;
&lt;p&gt;Now, what if that code we want to execute only once, depends on some condition. This condition might be &lt;code&gt;true&lt;/code&gt; when the object is initialized, meaning we can execute the code in the constructor as we did previously, but it may also be the case where the condition is initially &lt;code&gt;false&lt;/code&gt;, and at a later time becomes &lt;code&gt;true&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;&amp;hellip; The immediate answer should be clear.&lt;/p&gt;
&lt;p&gt;Generally, the inclination would be to check for that condition as it changes, cache it somewhere to detect how it is changing, and in order to make sure that piece of code is executed only once. Something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;conditionChanged&lt;/span&gt;&lt;span class="p"&gt;()&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;codeDidNotExecuteBefore&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;executeCode&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;The code above is really bad, and is the worst possible solution for this problem, probably. This doesn&amp;rsquo;t protect the function from other possible call sites, and decouples the condition from it&amp;rsquo;s actual purpose. Let&amp;rsquo;s fix that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;executeCodeOnce&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="n"&gt;codeDidNotExecuteBefore&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;codeDidNotExecuteBefore&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Much better. There is no way we might accidentally run the code twice this way (assuming single threaded environment). Also, the condition is tied to the code it&amp;rsquo;s guarding.&lt;/p&gt;
&lt;p&gt;Now, we can do even better, by getting rid of this explicit branching. Branching is generally bad and if we can avoid it, it&amp;rsquo;s much better, as it&amp;rsquo;s simpler to make sense of flat code that executes all sequential statements every time. Take a look:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;conditionChanged&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;executeCode&lt;/span&gt;&lt;span class="p"&gt;?()&lt;/span&gt;
    &lt;span class="n"&gt;executeCode&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;What happened here? Setting a function to &lt;code&gt;nil&lt;/code&gt;?! Well, this is a closure in Swift, and a closure is basically a pointer to a function. By putting the statements this way, we avoid any branching, while ensuring the code is still executed once&amp;hellip; Given that all call sites remember to set the closure to &lt;code&gt;nil&lt;/code&gt;!! How annoying, I though we were done.&lt;/p&gt;
&lt;h2&gt;The Abstraction&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;PerformOnce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;())?&lt;/span&gt;

    &lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;_&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="n"&gt;escaping&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&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="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kr"&gt;mutating&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;?()&lt;/span&gt;
        &lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, the simple abstraction to solve this problem, and hide as much of the unnecessary low-level complexity we don&amp;rsquo;t care about within another class we don&amp;rsquo;t have to worry about too much, as long as it&amp;rsquo;s heavily unit tested.&lt;/p&gt;
&lt;p&gt;With the code above, we can now do this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;doSomethingOnce&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PerformOnce&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;doSomethingOnce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;doSomethingOnce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;doSomethingOnce&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Even though there are 3 calls, the code will be executed once. No branching, no &lt;code&gt;nil&lt;/code&gt; setting, nothing! Just a very explicit and expressive variable name that indicates the code will be executed once, and indeed that&amp;rsquo;s what happens.&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Ready, Set, Hsssss!</title><link href="https://mazyod.com/blog/2018/08/18/ready-set-hsssss/" rel="alternate"></link><published>2018-08-18T14:43:09+00:00</published><updated>2018-08-18T14:43:09+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-08-18:/blog/2018/08/18/ready-set-hsssss/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I was waken up at 3:30 am by the sound of the fire alarm &amp;hellip; I tried to ignore it, but that deemed a fruitless effort. So, I moved to the living room, tried my luck there. No dice. So? Screw it. Go to the nearest Costa, have some …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I was waken up at 3:30 am by the sound of the fire alarm &amp;hellip; I tried to ignore it, but that deemed a fruitless effort. So, I moved to the living room, tried my luck there. No dice. So? Screw it. Go to the nearest Costa, have some coffee, and write a game!&lt;/p&gt;
&lt;p&gt;Actually, that&amp;rsquo;s what I&amp;rsquo;ve been contemplating since yesterday, to write a game with a clean architecture. I have never tried to write a game after acquiring the knowledge from Game Coding Complete book about game architectures.&lt;/p&gt;
&lt;h2&gt;A Game With a View&lt;/h2&gt;
&lt;p&gt;While &amp;ldquo;porting&amp;rdquo; my Dama game from Cocos to Unity, my 7 year old design couldn&amp;rsquo;t hold. I kept running into bugs and issues, and sought a better architecture. I don&amp;rsquo;t recall writing much about &amp;ldquo;Game View&amp;rdquo; approach, and doing a quick search on my blog shows only a hit at this design within the devlog.&lt;/p&gt;
&lt;p&gt;Basically, &amp;ldquo;Game Views&amp;rdquo; is a concept I borrowed from Game Coding Complete book, and it radically improved my Dama King implementation. The idea is simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A game view is both a driver + consumer of the game logic.&lt;/li&gt;
&lt;li&gt;AI agent, remote player, and even local game graphics are all views.&lt;ul&gt;
&lt;li&gt;AI agent consumes new turn event, and calculates it&amp;rsquo;s move.&lt;/li&gt;
&lt;li&gt;Remote player consumes a new turn by sending it over the wire.&lt;/li&gt;
&lt;li&gt;Local game graphics represent all the visuals of these events.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;New Game?&lt;/h2&gt;
&lt;p&gt;Why go with a complete new game?&lt;/p&gt;
&lt;p&gt;Well, Dama implementation is riddled with legacy decisions, and that will just take too much time and effort to unravel. Instead, to write a simple game, open-source it even, would prove to be a much better learning experience.&lt;/p&gt;
&lt;h2&gt;Get Down to It&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;4:56 AM&lt;/strong&gt; &lt;em&gt;Open Xcode, Create a new project&lt;/em&gt;
I think it&amp;rsquo;s best to write this in Swift, and make it a SpriteKit Game.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5:02 AM&lt;/strong&gt; &lt;em&gt;Exploring the SpriteKit template&lt;/em&gt;
I haven&amp;rsquo;t touched SpriteKit since 2015 &amp;hellip; It sure has changed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5:03 AM&lt;/strong&gt; &lt;em&gt;High-level Architecture&lt;/em&gt;
Regardless, let&amp;rsquo;s plow ahead. At a high-level, I would like to make a game that requires both an AI &lt;em&gt;and&lt;/em&gt; a multiplayer aspect. This means, at least a 3 player game&amp;hellip; Snake (the game I originally planned to write) won&amp;rsquo;t really do in that case&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5:08 AM&lt;/strong&gt; &lt;em&gt;Struggling to find the right game&amp;hellip;&lt;/em&gt;
What should it be? &amp;hellip; It should be a card game. A card game we call &amp;ldquo;War&amp;rdquo; where I come from. Basically, you should claim as many cards as possible, and to do so, you need &amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5:10 AM&lt;/strong&gt; &lt;em&gt;I&amp;rsquo;m making Swake after all!&lt;/em&gt;
Screw it, I&amp;rsquo;m making Swake. It will just have a single player mode, but that doesn&amp;rsquo;t mean I can&amp;rsquo;t leverage the Game View architecture!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5:12 AM&lt;/strong&gt; &lt;em&gt;Starting with the Game Logic&lt;/em&gt;
So, I&amp;rsquo;m starting with the game logic&amp;hellip; What is the game logic of a snake game?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Snake representation:&lt;ul&gt;
&lt;li&gt;Which blocks it covers&lt;/li&gt;
&lt;li&gt;Which direction it&amp;rsquo;s headed&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Food representation:&lt;ul&gt;
&lt;li&gt;Which block it covers&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Game Rules:&lt;ul&gt;
&lt;li&gt;Snake moves towards its set direction by one unit every turn&lt;/li&gt;
&lt;li&gt;Snake consumed food -&amp;gt; Grows by one unit&lt;/li&gt;
&lt;li&gt;Snake collided with walls/itself -&amp;gt; Game Over&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;5:37 AM&lt;/strong&gt; &lt;em&gt;Game Logic in place?&lt;/em&gt;
I now have this simple game logic representation in place &amp;hellip; I would like to get a simple graphics representation out of it next, and then a game loop to make it tick:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I removed a bunch of code, as this will hopefully be published in github anyway&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameLogic&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GameState&lt;/span&gt;

    &lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GameState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;food&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generateFoodPosition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;generateFoodPosition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Point&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;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;displaceSnakeOrGrow&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Game State:&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;GameState&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Snake&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;points&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Point&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;var&lt;/span&gt; &lt;span class="nv"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Food&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;position&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;snake&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Snake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;food&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Food&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;&lt;strong&gt;6:00 AM&lt;/strong&gt; &lt;em&gt;Crap is happening on the screen!&lt;/em&gt;
So, I just went with the most rough implementation, and just updated the &lt;code&gt;GameScene&lt;/code&gt; class which was part of the template to be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;_&lt;/span&gt; &lt;span class="n"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TimeInterval&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;gameLogic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;gameView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gameLogic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;state&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;&amp;hellip; and then, proceeded to implement the game view itself, as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;final&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GameGraphicalView&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GameView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;scene&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;SKScene&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;snake&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;SKNode&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;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;food&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;SKNode&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;tick&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GameState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;cleanUp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;prepareNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;positionNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;cleanUp&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="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;prepareNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GameState&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="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;positionNodes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GameState&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;This is extremely rough because I don&amp;rsquo;t do any kind of optimization nor animation. I simply remove all the objects, and then add them back again based on the new game state. It&amp;rsquo;s essentially recreating the whole scene, every single time.&lt;/p&gt;
&lt;p&gt;Ideally, we should simply generate &amp;ldquo;events&amp;rdquo; from the game logic, perhaps for another day&amp;hellip;&lt;/p&gt;
&lt;p&gt;For now, this is good enough, and I need to go check if my apartment is on fire or something&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;10:00 AM&lt;/strong&gt; &lt;em&gt;Insomnia&lt;/em&gt;
No matter how hard I try to sleep, it&amp;rsquo;s not possible &amp;hellip; Also, the my allergies made me snap, as I literally can&amp;rsquo;t keep my eyes open for 2 seconds straight&amp;hellip; So, it&amp;rsquo;s time to get your maid on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;12:52 PM&lt;/strong&gt; &lt;em&gt;A fresh start&lt;/em&gt;
Placebo or not, my allergies are significantly better, and it&amp;rsquo;s time to get back to it! &amp;hellip; First thing I want to do is implement controls!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1:08 PM&lt;/strong&gt; &lt;em&gt;Navigate away, Cap&amp;rsquo;!&lt;/em&gt;
Navigation is working, after a little bit or trouble converting input touches to the appropriate coordinate space, and doing the calculation based on that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;processTouch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CGPoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;topThird&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;!.&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;bottomThird&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;!.&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;centerX&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;!.&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;midX&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Direction&lt;/span&gt;
    &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;point&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="n"&gt;topThird&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;south&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottomThird&lt;/span&gt;&lt;span class="p"&gt;...):&lt;/span&gt;
        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;north&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="n"&gt;centerX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;_&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;west&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;centerX&lt;/span&gt;&lt;span class="p"&gt;...,&lt;/span&gt; &lt;span class="kc"&gt;_&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;direction&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;east&lt;/span&gt;
    &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="bp"&gt;fatalError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;can&amp;#39;t happen&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;gameLogic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;directionEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;direction&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, I would like to actually see the food, and a proper snake! Currently, it looks quite crappy, and the food is indistinguishable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1:25 PM&lt;/strong&gt; &lt;em&gt;Things are happening!&lt;/em&gt;
So, now I have a red snake moving about at a reasonable pace, and I can control its direction using &amp;ldquo;touch&amp;rdquo; controls! &amp;hellip; I just tried to run it on my device, but I&amp;rsquo;ve updated to iOS 12, and don&amp;rsquo;t have Xcode 10 installed&amp;hellip; Dang it!&lt;/p&gt;
&lt;p&gt;Anyways, so the biggest issue this time around was slowing the run loop. What happened was, after I applied the proper displacement calculation for the graphics based on the game logic representation of where the snake is, the snake would fly off the screen within a second.&lt;/p&gt;
&lt;p&gt;I initially thought this was a graphics problem, so I applied a slower loop on the graphical game view, using the &lt;code&gt;currentTime&lt;/code&gt; to calculate the time delta, but that just made the game &amp;ldquo;choppy&amp;rdquo;. I then realized, the game logic was still running at full speed! So, instead of applying the update throttle on the graphical view, I applied it all the way at the game scene, for both the game logic and the graphics.&lt;/p&gt;
&lt;p&gt;This is not ideal, as the graphics should update at 60 FPS! Only the game logic needs to have it&amp;rsquo;s run loop slowed down, as to control the speed of the snake and such&amp;hellip; But meh.&lt;/p&gt;
&lt;p&gt;Besides that, now I have a snake that grows as it eats stuff! Time to tackle two remaining concepts: Game Bounds + Game Over.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2:02 PM&lt;/strong&gt; &lt;em&gt;That took longer than expected&amp;hellip;&lt;/em&gt;
Game bounds was very tricky to get right. First, I couldn&amp;rsquo;t figure out if the border I was drawing was at all correct or not. Turns out it is, but the translation of GameLogic&amp;rsquo;s point to scene space was wrong, as it required some calculations and offset.&lt;/p&gt;
&lt;p&gt;Even with that out the way, I couldn&amp;rsquo;t find &lt;code&gt;anchorPoint&lt;/code&gt; property on &lt;code&gt;SKShapeNode&lt;/code&gt;, which led to a lot of manual work to tweak the Point -&amp;gt; Scene coordinate conversion formula. Eventually, managed to get it done.&lt;/p&gt;
&lt;p&gt;So .. Will slow the app down a bit, add game over logic, and call it a day.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2:27 PM&lt;/strong&gt; &lt;em&gt;Last few touches&lt;/em&gt;
After adding a game status enum to indicate whether the game ended or not, I actually found a lot of flaws in the implementation. I wasn&amp;rsquo;t resetting the user input buffer variable, I wasn&amp;rsquo;t cleaning the snake SKNodes properly as well&amp;hellip;&lt;/p&gt;
&lt;p&gt;I had to take it across the finish line, so I went ahead and showed a game over label when the game ends, and then automatically restarts on any tap.&lt;/p&gt;
&lt;h2&gt;Further Works&lt;/h2&gt;
&lt;p&gt;Even though this was a quick and dirty experimentation with Game View design, it proved worthwhile. What I would like to do with this is implement less dependency between GameLogic and the graphical representation, where they have their own run loops, and they communicate through events rather than the current polling/boil-the-ocean approach.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s da repo!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/Mazyod/Swake"&gt;https://github.com/Mazyod/Swake&lt;/a&gt;&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Problem Solving</title><link href="https://mazyod.com/blog/2018/07/22/problem-solving/" rel="alternate"></link><published>2018-07-22T09:04:11+00:00</published><updated>2018-07-22T09:04:11+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-07-22:/blog/2018/07/22/problem-solving/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I wanted to quickly write a python script that would solve a relatively simple problem. The problem is, I needed to generate a plist file based on data defined in a Swift file.&lt;/p&gt;
&lt;p&gt;This will involve file access, regular expressions, and file templates. Sounded a bit daunting at first …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I wanted to quickly write a python script that would solve a relatively simple problem. The problem is, I needed to generate a plist file based on data defined in a Swift file.&lt;/p&gt;
&lt;p&gt;This will involve file access, regular expressions, and file templates. Sounded a bit daunting at first, especially since I don&amp;rsquo;t have too much time to spend on this task, but I decided to do it anyway, and prove that by breaking down the problem, it shall be quite simple to resolve.&lt;/p&gt;
&lt;h2&gt;Divide &amp;amp; Conquer&lt;/h2&gt;
&lt;p&gt;Thankfully, there was some solution in place to solve this problem using Sourcery (a tool used generally for Swift code generation, not plists), however, the main reason I decided to move away from it was the lack of regex support. I mean, what kind of file processing tool doesn&amp;rsquo;t ship with regex support? Disappointing&amp;hellip;&lt;/p&gt;
&lt;p&gt;Anyhow&amp;hellip; So, with a solution in place, I didn&amp;rsquo;t have to write the plist file template from scratch, nor did I have to deal with figuring out all the file paths. I took them from the previous solution, and was ready to start!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="n"&gt;tweaks_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SRCROOT&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;..&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plist_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SRCROOT&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;sourcery&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plist_output&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;SRCROOT&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;..&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;OK, so the boilerplate is in place, what now?&lt;/p&gt;
&lt;p&gt;I was writing this script directly into the Xcode build phases field, lol. So, I didn&amp;rsquo;t have the luxury of an IDE or anything like that, hence I wanted to be able to quickly iterate and find bugs immediately. So, I first wrote how I expected the solution to look like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_mixpanel_tweak_ids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweaks_content&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;b&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;c&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_plist_templates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;file&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{tweaks}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/file&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;lt;tweak&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{display_name}&lt;/span&gt;&lt;span class="s2"&gt; - &lt;/span&gt;&lt;span class="si"&gt;{key_id}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/tweak&amp;gt;&amp;quot;&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_tweaks_xml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweak_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweak_template&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;tid&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tweak_ids&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;tweak_template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;not yet..&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key_id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;tid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;xml&lt;/span&gt;


&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweaks_file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;tweaks_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;mixpanel_tweak_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse_mixpanel_tweak_ids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweaks_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plist_template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;file_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweak_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;extract_plist_templates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;all_tweaks_xml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;generate_tweaks_xml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mixpanel_tweak_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweak_template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;final_content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;file_template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweaks&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;all_tweaks_xml&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plist_output&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;w+&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;final_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s it! I wrote how I expected the solution to work at a high-level, and them implemented the required functions as dummies in order to iterate on this first. Surely enough, in the code above, I found bugs due to typos, resolved them quickly, and the code was already working great!&lt;/p&gt;
&lt;p&gt;Next was the toughest part, which wasn&amp;rsquo;t too bad, and that is to implement the actual functions to do what they are suppose to.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll save you the boring details, and just say all it took was some regex magic. Again, I didn&amp;rsquo;t write this 100% correct from the get go, but due to the iteration approach, I quickly know where the bug was introduced, and can easily look to resolve it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_mixpanel_tweak_ids&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweaks_content&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;(?:let|var)\s*(.*?)\s*=\s*BoolTweak\(name:\s*&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;(.*?)&lt;/span&gt;&lt;span class="se"&gt;\&amp;quot;&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tweaks_content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;extract_plist_templates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;%template%(.*?)&lt;/span&gt;&lt;span class="si"&gt;%e&lt;/span&gt;&lt;span class="s2"&gt;ndtemplate%&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DOTALL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;file_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{tweaks}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tweak_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;regex&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;findall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;file_template&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tweak_template&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;generate_tweaks_xml&lt;/code&gt; I didn&amp;rsquo;t even have to change, since it was simple enough to work based on the initial implementation. The two functions above were quite heavy on the regex, and I was rusty &amp;hellip; So, I scratched my head quite a while to remember &lt;code&gt;re.DOTALL&lt;/code&gt; was needed to match dots to newlines.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The code above is written in a &amp;ldquo;functional programming&amp;rdquo; way, since the functions&amp;rsquo; outputs are only influenced by the input, and would give consistent results for the same input, no matter how many times they are called.&lt;/p&gt;
&lt;p&gt;This way of programming simplifies your life, leads to less bugs, and much more maintainable code. If I wanted to write tests for this as well, it would also be a breeze, for that matter.&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Snakes, Everywhere!</title><link href="https://mazyod.com/blog/2018/04/13/snakes-everywhere/" rel="alternate"></link><published>2018-04-13T19:29:23+00:00</published><updated>2018-04-13T19:29:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-04-13:/blog/2018/04/13/snakes-everywhere/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Ehm, for this one, I am really disappointed at my network of pythonistas. I was looking for such critical tool that would change my life forever when it comes to developing Python applications, yet no one could point to the ultimate solution I ended up finding by chance.&lt;/p&gt;
&lt;p&gt;The …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Ehm, for this one, I am really disappointed at my network of pythonistas. I was looking for such critical tool that would change my life forever when it comes to developing Python applications, yet no one could point to the ultimate solution I ended up finding by chance.&lt;/p&gt;
&lt;p&gt;The problem statement goes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I have a Python app I would like to distribute to my teammates&lt;/li&gt;
&lt;li&gt;The app is written in Python 3 with many dependencies&lt;/li&gt;
&lt;li&gt;My team size is 20+, and not everyone is well-versed with Python&lt;/li&gt;
&lt;li&gt;More over, some have a broken Python environment!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So &amp;hellip; I need a way to distribute a Python application, absolutely hassle-free. What are my options?&lt;/p&gt;
&lt;h2&gt;Eggs and Wheels&lt;/h2&gt;
&lt;p&gt;The most common solution I found online, and people proposed to me, is PyPi. Package your application as an Egg or Wheel, and use a distribution platform like PyPi.&lt;/p&gt;
&lt;h3&gt;Why Not&lt;/h3&gt;
&lt;p&gt;The reason this is bad is mainly because it still requires &lt;code&gt;pip&lt;/code&gt; and a proper python environment. Even if we assume that&amp;rsquo;s easily conquered with virtualenv, still dealing with the distribution is a pain. My app has some secrets I don&amp;rsquo;t want to get out, so &amp;hellip; Dealing with a private source is a pain.&lt;/p&gt;
&lt;h2&gt;Homebrew&lt;/h2&gt;
&lt;p&gt;I have another inclination, which I was so close to doing. Distribute through Homebrew. I had released a Homebrew formula before (&lt;a href="https://github.com/Mazyod/homebrew-truck"&gt;truck&lt;/a&gt;), so it was not that bad of an option.&lt;/p&gt;
&lt;p&gt;I started to look at the homebrew docs for defaults, and sure enough, homebrew runs your app in an isolated virtualenv, so you don&amp;rsquo;t need to worry about the users&amp;rsquo; mess.&lt;/p&gt;
&lt;h3&gt;Why Not&lt;/h3&gt;
&lt;p&gt;I ran into the same issue of private distribution. I thought I could solve that by giving out the secrets separately, and loading them using additional arguments. That is a legit solution.&lt;/p&gt;
&lt;p&gt;Then I realized, I also wanted to distribute a webapp alongside the Python server! How would I deal with the static file distribution? It&amp;rsquo;s probably solvable, but didn&amp;rsquo;t seem to me like a worthwhile endeavor.&lt;/p&gt;
&lt;h2&gt;Docker&lt;/h2&gt;
&lt;p&gt;Overkill.&lt;/p&gt;
&lt;h2&gt;PyInstaller&lt;/h2&gt;
&lt;p&gt;😍 My new favorite thing in Python. PyInstaller is an absolute kickass tool for distributing Python apps. All you do is point to your main script, and PyInstaller does the rest of the work.&lt;/p&gt;
&lt;p&gt;When configured properly, it can spit out a singl, stand-alone binary executable you can ship as a CLI app. That&amp;rsquo;s just grand. All I had to do next was a simple shell Mac OS Cocoa application that packages the binary alongside the required resources, and BAM. You now even have some GUI for your Python application, and it is distributed as a Mac OS app.&lt;/p&gt;
&lt;h2&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;With the power of a Mac OS app, I intend to provide a slick UX for interacting with the underlying Python app. Things like drag &amp;amp; drop your configuration files, as well as some logging and helper actions to tame the Python.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This post is really intended to take an overview about the available options for distributing Python apps, and doesn&amp;rsquo;t go into details on how to actually use PyInstaller effectively. That&amp;rsquo;s for another post....&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Pick Your Container</title><link href="https://mazyod.com/blog/2018/04/03/pick-your-container/" rel="alternate"></link><published>2018-04-03T19:30:43+00:00</published><updated>2018-04-03T19:30:43+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-04-03:/blog/2018/04/03/pick-your-container/</id><summary type="html">&lt;h2&gt;Dancing with the Snake&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been engrossed in Python development lately, since we have requirements to build a unified platform for UI testing tasks, such as publishing results, browsing screenshots, &amp;hellip; etc.&lt;/p&gt;
&lt;p&gt;Being a &amp;ldquo;seasoned&amp;rdquo; Python developer, I didn&amp;rsquo;t think twice about going with Flask, so everything was build …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Dancing with the Snake&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been engrossed in Python development lately, since we have requirements to build a unified platform for UI testing tasks, such as publishing results, browsing screenshots, &amp;hellip; etc.&lt;/p&gt;
&lt;p&gt;Being a &amp;ldquo;seasoned&amp;rdquo; Python developer, I didn&amp;rsquo;t think twice about going with Flask, so everything was build on top of that. However, after proceeding to add more UI tests, I ran into such an &amp;ldquo;unforgivable&amp;rdquo; error .. Flask wasn&amp;rsquo;t detecting the HTTP method of the request properly :S&lt;/p&gt;
&lt;h2&gt;A Leaky Flask&lt;/h2&gt;
&lt;p&gt;For whatever reason, when our app would send two consecutive requests, where the first request has a JSON body, the second request is improperly handled by the flask dev server .. It show something like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&amp;quot;{&amp;quot;foo&amp;quot;: &amp;quot;bar&amp;quot;}GET /api/path&amp;quot; 405
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, the http method resolved contains the string from the previous request body, which then causes a method not allowed mismatch. I was in utter disbelief, and was certain it was due to HTTP pipelining or some other optimization on the client&amp;hellip;&lt;/p&gt;
&lt;p&gt;After digging deep and wide in the iOS code, no avail. Everything checks out fine, and Charles shows all requests properly .. It&amp;rsquo;s time to get inventive.&lt;/p&gt;
&lt;h2&gt;A Speedy Pivot&lt;/h2&gt;
&lt;p&gt;No idea how it hit me, but I recalled all of a sudden &amp;ldquo;bottle&amp;rdquo;. The python micro-framework that works in an almost identical fashion as Flask .. It was gonna be time consuming, but with nothing else in mind, I moved forward with the migration.&lt;/p&gt;
&lt;p&gt;After learning bottle basics, I was able to migrate the basic APIs with super minimal changes, and got the server up and running. That took maybe 15 minutes at most. Once I did that, I ran the UI tests again, and surely enough, the http method bug was resolved!! Yatta!&lt;/p&gt;
&lt;p&gt;With this confidence boost, I proceeded to migrate the rest of the server parts to bottle, and completely nuked Flask. I guess that took about an hour or so&amp;hellip; I&amp;rsquo;m now a very happy bottle user, and it is worth mentioning, bottle is WAY faster in launching and processing requests, for my case at least.&lt;/p&gt;
&lt;h2&gt;Migrating from Flask to Bottle&lt;/h2&gt;
&lt;p&gt;Here are my learnings for migrating from Flask to bottle:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gd"&gt;-import flask&lt;/span&gt;
&lt;span class="gd"&gt;-from werkzeug.http import Headers&lt;/span&gt;
&lt;span class="gi"&gt;+import bottle&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;[ ... ]

&lt;span class="gi"&gt;+# Remove &amp;quot;hop-by-hop&amp;quot; headers (as defined by RFC2613, Section 13)&lt;/span&gt;
&lt;span class="gi"&gt;+# since they are not allowed by the WSGI standard.&lt;/span&gt;
&lt;span class="gi"&gt;+FILTER_HEADERS = [&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Connection&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Keep-Alive&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Proxy-Authenticate&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Proxy-Authorization&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;TE&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Trailers&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Transfer-Encoding&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+    &amp;#39;Upgrade&amp;#39;,&lt;/span&gt;
&lt;span class="gi"&gt;+]&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+PROJECT_DIR = os.path.dirname(__file__)&lt;/span&gt;
&lt;span class="gi"&gt;+WEB_ROOT = os.path.join(PROJECT_DIR, &amp;quot;snap-audit&amp;quot;, &amp;quot;build&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+STATIC_ROOT = os.path.join(WEB_ROOT, &amp;quot;static&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;[ ... ]

&lt;span class="w"&gt; &lt;/span&gt;# Server
&lt;span class="w"&gt; &lt;/span&gt;#

&lt;span class="gd"&gt;-app = flask.Flask(__name__, static_folder=&amp;#39;snap-audit/build&amp;#39;)&lt;/span&gt;
&lt;span class="gd"&gt;-&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;[ ... ]

&lt;span class="w"&gt; &lt;/span&gt;# global handlers

&lt;span class="gd"&gt;-@app.errorhandler(400)&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.error(400)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def bad_request(e):
&lt;span class="gd"&gt;-    return flask.jsonify(error=400, text=str(e)), 400&lt;/span&gt;
&lt;span class="gi"&gt;+    return dict(error=400, text=str(e))&lt;/span&gt;


&lt;span class="gd"&gt;-@app.errorhandler(404)&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.error(404)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def page_not_found(e):
&lt;span class="gd"&gt;-    return flask.jsonify(error=404, text=str(e)), 404&lt;/span&gt;
&lt;span class="gi"&gt;+    return dict(error=404, text=str(e))&lt;/span&gt;


&lt;span class="gd"&gt;-@app.route(&amp;#39;/&amp;#39;)&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.get(&amp;#39;/&amp;#39;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def root_path():
&lt;span class="gd"&gt;-    return flask.jsonify(status=&amp;quot;ok&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    return {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}&lt;/span&gt;


&lt;span class="w"&gt; &lt;/span&gt;# mock-server-api

&lt;span class="gd"&gt;-@app.route(&amp;#39;/mock-server-api/mount&amp;#39;, methods=[&amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.route(&amp;#39;/mock-server-api/mount&amp;#39;, method=&amp;quot;ANY&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def mock_server_mount():
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;Mounts a given postman group
&lt;span class="w"&gt; &lt;/span&gt;    Expected Query: ?group={group_name}
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;span class="gd"&gt;-    group = flask.request.args.get(&amp;quot;group&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    group = bottle.request.query.group&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    if not group:
&lt;span class="gd"&gt;-        flask.abort(400, description=&amp;quot;missing query parameter &amp;#39;group&amp;#39;&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+        bottle.abort(400, &amp;quot;missing query parameter &amp;#39;group&amp;#39;&amp;quot;)&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;    if not mounting_service.push_group(group):
&lt;span class="gd"&gt;-        flask.abort(400, description=&amp;quot;group not found&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+        bottle.abort(400, &amp;quot;group not found&amp;quot;)&lt;/span&gt;

&lt;span class="gd"&gt;-    return flask.jsonify(status=&amp;quot;ok&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    return {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}&lt;/span&gt;


&lt;span class="gd"&gt;-@app.route(&amp;#39;/mock-server-api/unmount&amp;#39;, methods=[&amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.route(&amp;#39;/mock-server-api/unmount&amp;#39;, method=&amp;quot;ANY&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def mock_server_unmount():
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;Unmounts a given postman group, otherwise unmounts all groups.
&lt;span class="w"&gt; &lt;/span&gt;    Expected Query: ?group={group_name}
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;span class="gd"&gt;-    group = flask.request.args.get(&amp;quot;group&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    group = bottle.request.query.group&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    if group:
&lt;span class="w"&gt; &lt;/span&gt;        mounting_service.unmount_group(group)
&lt;span class="w"&gt; &lt;/span&gt;    else:
&lt;span class="w"&gt; &lt;/span&gt;        mounting_service.unmount_all_groups()

&lt;span class="gd"&gt;-    return flask.jsonify(status=&amp;quot;ok&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    return {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}&lt;/span&gt;


&lt;span class="w"&gt; &lt;/span&gt;# mock-server

&lt;span class="gd"&gt;-@app.route(&amp;#39;/mock-server/&amp;lt;path:mock_path&amp;gt;&amp;#39;, methods=[&amp;quot;GET&amp;quot;, &amp;quot;POST&amp;quot;, &amp;quot;PUT&amp;quot;, &amp;quot;PATCH&amp;quot;, &amp;quot;DELETE&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.route(&amp;#39;/mock-server/&amp;lt;mock_path:re:.+&amp;gt;&amp;#39;, method=&amp;quot;ANY&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def mock_server(mock_path):
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;Serves the designated mock postman collection&amp;quot;&amp;quot;&amp;quot;
&lt;span class="w"&gt; &lt;/span&gt;    item = mounting_service.item_for(mock_path)
&lt;span class="w"&gt; &lt;/span&gt;    if not item:
&lt;span class="gd"&gt;-        flask.abort(404)&lt;/span&gt;
&lt;span class="gi"&gt;+        bottle.abort(404)&lt;/span&gt;

&lt;span class="w"&gt; &lt;/span&gt;    # TODO - perhaps find required example?
&lt;span class="w"&gt; &lt;/span&gt;    response = item.response[0]
&lt;span class="w"&gt; &lt;/span&gt;    jstring = response[&amp;quot;body&amp;quot;]
&lt;span class="w"&gt; &lt;/span&gt;    status = response[&amp;quot;code&amp;quot;]
&lt;span class="w"&gt; &lt;/span&gt;    # TODO - enable gzip encoding
&lt;span class="gd"&gt;-    ignored_headers = [&amp;quot;Content-Encoding&amp;quot;]&lt;/span&gt;
&lt;span class="gd"&gt;-    headers = [h for h in response[&amp;quot;header&amp;quot;] if h[&amp;quot;key&amp;quot;] not in ignored_headers]&lt;/span&gt;
&lt;span class="gi"&gt;+    headers = [h for h in response[&amp;quot;header&amp;quot;] if h[&amp;quot;key&amp;quot;] not in FILTER_HEADERS]&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+    bottle.response.status = status&lt;/span&gt;
&lt;span class="gi"&gt;+    bottle.response.content_type = &amp;quot;application/json&amp;quot;&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+    for h in headers:&lt;/span&gt;
&lt;span class="gi"&gt;+        bottle.response.set_header(h[&amp;quot;key&amp;quot;], h[&amp;quot;value&amp;quot;])&lt;/span&gt;

&lt;span class="gd"&gt;-    return app.response_class(response=jstring,&lt;/span&gt;
&lt;span class="gd"&gt;-                              status=status,&lt;/span&gt;
&lt;span class="gd"&gt;-                              headers=Headers([(h[&amp;quot;key&amp;quot;], h[&amp;quot;value&amp;quot;]) for h in headers]),&lt;/span&gt;
&lt;span class="gd"&gt;-                              mimetype=&amp;quot;application/json&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    return jstring&lt;/span&gt;


&lt;span class="w"&gt; &lt;/span&gt;# postman-dump

&lt;span class="gd"&gt;-@app.route(&amp;#39;/postman-dump&amp;#39;, methods=[&amp;quot;POST&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.post(&amp;#39;/postman-dump&amp;#39;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def postman_dump():
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;Postman recording API. Incoming request will be captured into a postman collection
&lt;span class="w"&gt; &lt;/span&gt;    Expected format:
&lt;span class="gu"&gt;@@ -295,52 +313,64 @@ def postman_dump():&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;      }
&lt;span class="w"&gt; &lt;/span&gt;    }
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;span class="gd"&gt;-    capture_service.add(flask.request.json)&lt;/span&gt;
&lt;span class="gd"&gt;-    return flask.jsonify(status=&amp;quot;ok&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    capture_service.add(bottle.request.json)&lt;/span&gt;
&lt;span class="gi"&gt;+    return {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}&lt;/span&gt;


&lt;span class="w"&gt; &lt;/span&gt;# snap-audit

&lt;span class="gd"&gt;-@app.route(&amp;#39;/snap-audit&amp;#39;, methods=[&amp;quot;GET&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.get(&amp;#39;/snap-audit&amp;#39;)&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.get(&amp;#39;/index.html&amp;#39;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def serve_snap_audit():
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;snap audit is our React.js app&amp;quot;&amp;quot;&amp;quot;
&lt;span class="gd"&gt;-    return flask.send_from_directory(&amp;quot;snap-audit/build&amp;quot;, &amp;quot;index.html&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    return bottle.static_file(&amp;quot;index.html&amp;quot;, WEB_ROOT)&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.get(&amp;#39;/manifest.json&amp;#39;)&lt;/span&gt;
&lt;span class="gi"&gt;+def serve_snap_audit():&lt;/span&gt;
&lt;span class="gi"&gt;+    return bottle.static_file(&amp;quot;manifest.json&amp;quot;, WEB_ROOT)&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.get(&amp;#39;/service-worker.js&amp;#39;)&lt;/span&gt;
&lt;span class="gi"&gt;+def serve_snap_audit():&lt;/span&gt;
&lt;span class="gi"&gt;+    return bottle.static_file(&amp;quot;service-worker.js&amp;quot;, WEB_ROOT)&lt;/span&gt;


&lt;span class="gd"&gt;-@app.route(&amp;#39;/static/&amp;lt;path:path&amp;gt;&amp;#39;)&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.route(&amp;#39;/static/&amp;lt;path:re:.+&amp;gt;&amp;#39;, method=&amp;quot;ANY&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def serve_static_asset(path):
&lt;span class="gd"&gt;-    return flask.send_from_directory(&amp;#39;snap-audit/build/static&amp;#39;, path)&lt;/span&gt;
&lt;span class="gi"&gt;+    return bottle.static_file(path, STATIC_ROOT)&lt;/span&gt;


&lt;span class="gd"&gt;-@app.route(&amp;#39;/snap-audit/test-result&amp;#39;, methods=[&amp;quot;POST&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.route(&amp;#39;/snap-audit/test-result&amp;#39;, method=&amp;quot;ANY&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def record_test_result():
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;Records the given test result as part of the test metadata
&lt;span class="w"&gt; &lt;/span&gt;    Expected Header: Content-Type: application/json
&lt;span class="w"&gt; &lt;/span&gt;    Expected Query: ?path=feature/variant/environment
&lt;span class="w"&gt; &lt;/span&gt;    Expected Body: {&amp;quot;success&amp;quot;: bool}
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;
&lt;span class="gd"&gt;-    path = flask.request.args.get(&amp;quot;path&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    path = bottle.request.query.path&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    if not path:
&lt;span class="gd"&gt;-        flask.abort(400, description=&amp;quot;please provide path query item&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+        bottle.abort(400, &amp;quot;please provide path query item&amp;quot;)&lt;/span&gt;

&lt;span class="gd"&gt;-    firebase.upload_test_result(path, flask.request.json)&lt;/span&gt;
&lt;span class="gd"&gt;-    return flask.jsonify(status=&amp;quot;ok&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    firebase.upload_test_result(path, bottle.request.json)&lt;/span&gt;
&lt;span class="gi"&gt;+    return {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}&lt;/span&gt;


&lt;span class="gd"&gt;-@app.route(&amp;#39;/snap-audit/screenshot/upload&amp;#39;, methods=[&amp;quot;POST&amp;quot;, &amp;quot;PUT&amp;quot;])&lt;/span&gt;
&lt;span class="gi"&gt;+@bottle.route(&amp;#39;/snap-audit/screenshot/upload&amp;#39;, method=&amp;quot;ANY&amp;quot;)&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;def upload_screenshot():
&lt;span class="w"&gt; &lt;/span&gt;    &amp;quot;&amp;quot;&amp;quot;Uploads the given image asynchronously to our storage service. The reason we ask for arbitrary path variable is
&lt;span class="w"&gt; &lt;/span&gt;    to allow clients to decide their preferred way to structure their screenshots.
&lt;span class="w"&gt; &lt;/span&gt;    Expected Header: Content-Type: image/png
&lt;span class="w"&gt; &lt;/span&gt;    Expected Query: ?path=feature/variant/environment&amp;amp;index=3&amp;quot;&amp;quot;&amp;quot;
&lt;span class="gd"&gt;-    path = flask.request.args.get(&amp;quot;path&amp;quot;)&lt;/span&gt;
&lt;span class="gd"&gt;-    index = flask.request.args.get(&amp;quot;index&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    path = bottle.request.query.path&lt;/span&gt;
&lt;span class="gi"&gt;+    index = bottle.request.query.index&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;    if not path or not index:
&lt;span class="gd"&gt;-        flask.abort(400, description=&amp;quot;please provide path and index query items&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+        bottle.abort(400, &amp;quot;please provide path and index query items&amp;quot;)&lt;/span&gt;

&lt;span class="gd"&gt;-    firebase.upload_screenshot(path, index, flask.request.data)&lt;/span&gt;
&lt;span class="gd"&gt;-    return flask.jsonify(status=&amp;quot;ok&amp;quot;)&lt;/span&gt;
&lt;span class="gi"&gt;+    firebase.upload_screenshot(path, index, bottle.request.body.read())&lt;/span&gt;
&lt;span class="gi"&gt;+    return {&amp;quot;status&amp;quot;: &amp;quot;ok&amp;quot;}&lt;/span&gt;


&lt;span class="w"&gt; &lt;/span&gt;if __name__ == &amp;#39;__main__&amp;#39;:
&lt;span class="gd"&gt;-    app.run(host=&amp;#39;0.0.0.0&amp;#39;, port=5858)&lt;/span&gt;
&lt;span class="gi"&gt;+    bottle.debug(True)&lt;/span&gt;
&lt;span class="gi"&gt;+    bottle.run(host=&amp;#39;0.0.0.0&amp;#39;, port=5858)&lt;/span&gt;
&lt;span class="gh"&gt;diff --git a/requirements.txt b/requirements.txt&lt;/span&gt;
&lt;span class="gh"&gt;index be2a752..b78e1e9 100644&lt;/span&gt;
&lt;span class="gd"&gt;--- a/requirements.txt&lt;/span&gt;
&lt;span class="gi"&gt;+++ b/requirements.txt&lt;/span&gt;
&lt;span class="gu"&gt;@@ -1,9 +1,8 @@&lt;/span&gt;
&lt;span class="gi"&gt;+bottle==0.12.13&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;cachetools==2.0.1
&lt;span class="w"&gt; &lt;/span&gt;certifi==2018.1.18
&lt;span class="w"&gt; &lt;/span&gt;chardet==3.0.4
&lt;span class="gd"&gt;-click==6.7&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;firebase-admin==2.9.1
&lt;span class="gd"&gt;-Flask==0.12.2&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;google-api-core==1.1.0
&lt;span class="w"&gt; &lt;/span&gt;google-auth==1.4.1
&lt;span class="w"&gt; &lt;/span&gt;google-cloud-core==0.28.1
&lt;span class="gu"&gt;@@ -12,9 +11,6 @@ google-cloud-storage==1.8.0&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;google-resumable-media==0.3.1
&lt;span class="w"&gt; &lt;/span&gt;googleapis-common-protos==1.5.3
&lt;span class="w"&gt; &lt;/span&gt;idna==2.6
&lt;span class="gd"&gt;-itsdangerous==0.24&lt;/span&gt;
&lt;span class="gd"&gt;-Jinja2==2.10&lt;/span&gt;
&lt;span class="gd"&gt;-MarkupSafe==1.0&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;protobuf==3.5.2.post1
&lt;span class="w"&gt; &lt;/span&gt;pyasn1==0.4.2
&lt;span class="w"&gt; &lt;/span&gt;pyasn1-modules==0.2.1
&lt;span class="gu"&gt;@@ -23,4 +19,3 @@ requests==2.18.4&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;rsa==3.4.2
&lt;span class="w"&gt; &lt;/span&gt;six==1.11.0
&lt;span class="w"&gt; &lt;/span&gt;urllib3==1.22
&lt;span class="gd"&gt;-Werkzeug==0.14.1&lt;/span&gt;
&lt;span class="gd"&gt;-- &lt;/span&gt;
2.15.1 (Apple Git-101)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Ecto.Multi</title><link href="https://mazyod.com/blog/2018/03/29/ectomulti/" rel="alternate"></link><published>2018-03-29T02:46:53+00:00</published><updated>2018-03-29T02:46:53+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-03-29:/blog/2018/03/29/ectomulti/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I have been ignoring errors coming in from my backend for a while now .. There is only one serious and frequent error, actually, and I&amp;rsquo;ve no idea how it&amp;rsquo;s happening, so decided to ignore it .. That was a grave mistake.&lt;/p&gt;
&lt;p&gt;Today, a user reached out and complained …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I have been ignoring errors coming in from my backend for a while now .. There is only one serious and frequent error, actually, and I&amp;rsquo;ve no idea how it&amp;rsquo;s happening, so decided to ignore it .. That was a grave mistake.&lt;/p&gt;
&lt;p&gt;Today, a user reached out and complained about his purchases not reflecting on his account! That&amp;rsquo;s quite serious, and needed to be dealt with ASAP&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Debugging&lt;/h2&gt;
&lt;p&gt;First, I looked at all the logs I had, and that&amp;rsquo;s a really annoying chore &amp;hellip; I have logs on Papertrail, heroku, custom logging server, and sentry. Yeah .. I was paranoid about the time where I would need to debug purchases, and indeed, that time has come.&lt;/p&gt;
&lt;p&gt;The best thing was, the logged exception on sentry had the exact payload sent from the client, hence I was able to replay the request, and get the same error. Perfect! Reproducibility, check!&lt;/p&gt;
&lt;p&gt;Now, what is the error? Actually, elixir/phoenix apps default to 8 frames on the stacktrace, so all I could see was:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;Elixir.DBConnection.ConnectionError: transaction rolling back
  File &amp;quot;lib/db_connection.ex&amp;quot;, line 1523, in DBConnection.fetch_info/1
  File &amp;quot;lib/db_connection.ex&amp;quot;, line 738, in DBConnection.run/3
  File &amp;quot;lib/db_connection.ex&amp;quot;, line 636, in DBConnection.execute/4
  File &amp;quot;lib/ecto/adapters/postgres/connection.ex&amp;quot;, line 105, in Ecto.Adapters.Postgres.Connection.execute/4
  File &amp;quot;lib/ecto/adapters/sql.ex&amp;quot;, line 243, in Ecto.Adapters.SQL.sql_call/6
  File &amp;quot;lib/ecto/adapters/sql.ex&amp;quot;, line 441, in Ecto.Adapters.SQL.execute_or_reset/7
  File &amp;quot;lib/ecto/repo/queryable.ex&amp;quot;, line 130, in Ecto.Repo.Queryable.execute/5
  File &amp;quot;lib/ecto/repo/queryable.ex&amp;quot;, line 35, in Ecto.Repo.Queryable.all/4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Dang it!! But you know what the beauty was? I had the foresight to split my backend into micro-services :D .. The affected server was hosted on Heroku, and publishing a new version was as simple as pushing a new commit to Github.&lt;/p&gt;
&lt;p&gt;Hence, I configured phoenix to show more stackes, and pushed a new release:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;config :phoenix, :stacktrace_depth, 20
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;The Culprit&lt;/h2&gt;
&lt;p&gt;After seeing the 20 line stacktrace, even that didn&amp;rsquo;t make sense, lol, but it at least confirmed my suspicion of which function the error was being thrown.&lt;/p&gt;
&lt;p&gt;After looking deep and hard at the function, I was finally able to see it .. it was there, as clear as day&amp;hellip; The function, which was part of an &lt;code&gt;Ecto.Multi&lt;/code&gt; was handling a &lt;code&gt;Repo.insert&lt;/code&gt; with a &lt;code&gt;with&lt;/code&gt; statement that &amp;ldquo;suppressed&amp;rdquo; a certain DB error that detected duplicate purchase receipts&amp;hellip; You can&amp;rsquo;t do that.&lt;/p&gt;
&lt;p&gt;You see, if a DB error is thrown during a transaction, the whole transaction is marked as invalid, and you should rollback before you can start querying the db again. The rollback for &lt;code&gt;Ecto.Multi&lt;/code&gt; happens at the end, so I couldn&amp;rsquo;t suppress this error, unfortunately.&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;Even being away from this code for a freakin year now, I wrote a simple solution that first enumerates the purchases, and filters out duplicates found in the DB. The tests passed from the first try&amp;hellip; I was in disbelief.&lt;/p&gt;
&lt;p&gt;I changed the function around to break the tests, truly enough, the failed as intended. I kept changing things around just to make sure I&amp;rsquo;m not missing anything, and nope .. nothing was missing at all. The code simply works. Elixir is the freakin best.&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Mining, ethOS and Bots!</title><link href="https://mazyod.com/blog/2018/03/24/mining-ethos-and-bots/" rel="alternate"></link><published>2018-03-24T22:33:57+00:00</published><updated>2018-03-24T22:33:57+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-03-24:/blog/2018/03/24/mining-ethos-and-bots/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been into mining Crypto-currencies recently (I&amp;rsquo;m not sure what&amp;rsquo;s the proper way to type that, so will refer to them as cryptos from now on .. with the added bonus of triggering cryptography nerds :troll:).&lt;/p&gt;
&lt;p&gt;So, what&amp;rsquo;s the big deal? I&amp;rsquo;m actually quite late …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been into mining Crypto-currencies recently (I&amp;rsquo;m not sure what&amp;rsquo;s the proper way to type that, so will refer to them as cryptos from now on .. with the added bonus of triggering cryptography nerds :troll:).&lt;/p&gt;
&lt;p&gt;So, what&amp;rsquo;s the big deal? I&amp;rsquo;m actually quite late to hop on the bandwagon to be honest. People have been mining ever since the inception of Bitcoin, and that was way back when &amp;hellip; The deal is, I&amp;rsquo;ve applied some python goodness to the mining operations.&lt;/p&gt;
&lt;p&gt;Since I use &lt;a href="http://ethosdistro.com/"&gt;ethOS&lt;/a&gt; on my mining rigs, it has been an extremely pleasurable experience configuring and monitoring the rigs. The best part of all this is that the rigs are a source of income rather than another unjustified subscription to satisfy my unquenchable geekness.&lt;/p&gt;
&lt;p&gt;Without further ado, let&amp;rsquo;s breaking this story down. The post is covering these main points:
- What is mining?
- How&amp;rsquo;s ethOS working for far?
- Solving the monitoring problem&lt;/p&gt;
&lt;h2&gt;Solving Math Problems&lt;/h2&gt;
&lt;p&gt;Mining is actually a really clever pun invented by the crypto lords to describe the process of earning cryptos. Gold, even today, is considered to be a valuable material due to its scarcity and defined availability. You can&amp;rsquo;t synthesize gold out of thin air, and once all the gold on the plant has been &lt;strong&gt;mined&lt;/strong&gt;, that&amp;rsquo;s it .. People can only circulate the existing gold.&lt;/p&gt;
&lt;p&gt;Now, given that you, me, Alice, bob, or anyone for that matter can try their luck and go try mining for gold, and finding gold through such means is fair game, one could say that is a possible way to try and earn a living or perhaps be rich.&lt;/p&gt;
&lt;p&gt;Given that definition above, the exact same principle applies to Cryptos. Through an ingenious system developed on top of the blockchain technology, humans were able to somehow come up with a software system that functions in the same way as gold! The main catch here is, literally &lt;em&gt;anyone&lt;/em&gt; can define their own Crypto, as opposed to no one being able to define their own &amp;ldquo;gold&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;So, with that said, the process of mining Crypto, not surprisingly, does not involve digging a mine or any physical activity. After all, the whole system is software-based! How does one mine Cryptos then?&lt;/p&gt;
&lt;p&gt;Well, without getting into the hairy details of Cryptos, let&amp;rsquo;s just say that Cryptos&amp;rsquo; reward system is based on lottery, where the more computing power you have gives you a better chance of winning the lottery. (In retrospect, having more gold mining operations means you have better chances of finding more gold).&lt;/p&gt;
&lt;p&gt;I am sure you have lots of questions about this, but let&amp;rsquo;s just leave this here, and move on the to the next topic.&lt;/p&gt;
&lt;h2&gt;The Mighty ethOS&lt;/h2&gt;
&lt;p&gt;ethOS is by far the easiest way to get a mining machine up and running (for me at least). Alternatives I&amp;rsquo;ve tinkered with were simplemining.net and the dreaded Windows 10. Both were surprisingly painful to deal with, and had extremely limited support online in terms of identifying similar issues we were facing.&lt;/p&gt;
&lt;p&gt;I mean, think about it. Windows 10 is such a bloated operating system relative to most Linux distros, and everyone has their variation of Windows installation, with a different permutation of software and drivers installed. Hence, it seems people are not able to debug issues properly and detect problems with their setup.&lt;/p&gt;
&lt;p&gt;Besides that, it&amp;rsquo;s not as programmer friendly as a Linux distro, such as ethOS. I haven&amp;rsquo;t done it yet, but spinning up a crontab with custom scripts to perform my biddings is &lt;a href="https://youtu.be/4I39dmsWKpw"&gt;easy-peasy, lemon squeezy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Finally, also in contrast with the other options I&amp;rsquo;ve tried, ethOS simply has all the drivers and scripts you need built-in. I&amp;rsquo;ve had to run some extra commands to make MSI z270-A PRO and GTX 1060 Rev2 6GB work, but those steps were all properly documented on the ethOS online knowledge base.&lt;/p&gt;
&lt;p&gt;To be quite frank tho, some crap was quite annoying to get your head around, especially the config stuff. I used local config for no reason initially, then realized I can just just use gist.github.com for that. Also, there is configmaker thingie advertised by ethOS, but I really want a private, secure config, so &amp;hellip; gist was the way to go for me.&lt;/p&gt;
&lt;p&gt;P.S. ethOS has built in TeamViewer support, and it is truly kickass.&lt;/p&gt;
&lt;h2&gt;Better Than Slack&lt;/h2&gt;
&lt;p&gt;Slack has been my go-to platform for receiving alerts and such .. up until I found out how easy it was to write a Telegram bot. Instead of spinning up a webhook, and dealing with all the setup, which has some very rigid and annoying limitations, Telegram opens a world of possibilities.&lt;/p&gt;
&lt;p&gt;So, the story goes &amp;hellip; After setting up the rigs, sometimes the rigs would malfunction, and a GPU or two or all would stop hashing. I would like to know about that, so &amp;hellip; I noticed that the ethOS panel website provides a JSON api. Hence, why not monitor the API, and trigger me some alerts? Alerts on where?&lt;/p&gt;
&lt;p&gt;Given that Telegram is the platform of Crypto, might as well just do it there. It would be a nice exercise as well to finally write me own Telegram Bot. And so, &lt;a href="https://github.com/Mazyod/ethogram"&gt;ethogram&lt;/a&gt; was born.&lt;/p&gt;
&lt;p&gt;With ethogram, we were able to monitor our rigs from within the Telegram group, and given the bot was written in Python, it was absolutely trivial to write various alerts on different metrics. It took me some time to come up with an optimal design for the classes and such, especially when I decided to add unit tests, but since then, I think it is at a perfect place&amp;hellip; And now, I want to port it to Elixir xD&lt;/p&gt;
&lt;h2&gt;Next&lt;/h2&gt;
&lt;p&gt;Honestly, I&amp;rsquo;ve been contemplating moving to Elixir since I want to write a more reliable, extensible platform that doesn&amp;rsquo;t just monitor ethOS, but also tracks Crypto prices, mining pools, profitability, &amp;hellip; etc.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t think I&amp;rsquo;m gonna be doing that anytime soon, if at all, tho &amp;hellip; I need to focus on finalizing the UI Testing project I&amp;rsquo;ve been committed to for the past 5 months or so first&amp;hellip; It&amp;rsquo;s annoying to have such a project lingering around for so long!! Put it&amp;rsquo;s at a pretty kickass state right now &amp;hellip; Once that&amp;rsquo;s over, I would like to switch my attention to A.I. for a bit, so look forward to reading about that soon!!&lt;/p&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Hello... Again.</title><link href="https://mazyod.com/blog/2018/03/24/hello-again/" rel="alternate"></link><published>2018-03-24T21:33:16+00:00</published><updated>2018-03-24T21:33:16+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2018-03-24:/blog/2018/03/24/hello-again/</id><summary type="html">&lt;h2&gt;Just Type&lt;/h2&gt;
&lt;p&gt;I literally just want to breathe some life into the blog again .. I am not sure what I want to write about, but I do want to address the fact that I haven&amp;rsquo;t written anything for so long, and I really miss this part of my life …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Just Type&lt;/h2&gt;
&lt;p&gt;I literally just want to breathe some life into the blog again .. I am not sure what I want to write about, but I do want to address the fact that I haven&amp;rsquo;t written anything for so long, and I really miss this part of my life.&lt;/p&gt;
&lt;p&gt;Well, although this is supposedly a dev diary, every now and then I talk about life.. The life of a dev is weird, and is intertwined with his profession&amp;hellip;&lt;/p&gt;
&lt;p&gt;Unless you are an extremely &amp;hellip; unique type of person, it is extremely hard to just sit in front of a computer and just crank out code. Why? I really don&amp;rsquo;t know, and would really like to find out&amp;hellip; Why can&amp;rsquo;t I just sit in front of the computer for a month, and just type &amp;hellip; type away at all these projects I would like to finish &amp;hellip;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m pretty sure I&amp;rsquo;ve touched upon this in the past, mentioning it might be the fear of failure. But &amp;hellip; what failure? Every programming project, shipped or not, is an addition to your arsenal of knowledge. Programming knowledge doesn&amp;rsquo;t die with a failed project ..  In contrast, it actually becomes just a firm part of your thought process, as that pain of failure warns you about the mishaps that had occurred.&lt;/p&gt;
&lt;p&gt;Too philosophical, I know &amp;hellip; I&amp;rsquo;ve fallen a victim to YouTube during burnout, just as one other fellow developer has expressed. I totally related to his situation, and that is such a relief to be honest. We continuously forget that we don&amp;rsquo;t face problems alone. It is always true that the problem of any individual, especially in this time and era, is the problem of society.&lt;/p&gt;
&lt;p&gt;Lol, that was &amp;hellip; weird. Anyway, what I wanted to point out is, if you face a problem, take a step back &amp;hellip; Diagnose the problem, and if it is considered by your standards a significant problem, think of all the other people in your shoes facing the exact same problem &amp;hellip; Then perhaps set out to solve that.&lt;/p&gt;
&lt;h2&gt;Beyond Typing&lt;/h2&gt;
&lt;p&gt;OK .. so the hard part of getting start, and back to blogging is over. I&amp;rsquo;ve typed a whole bunch of stuff above, and it seems like I am back in business!! Well, might as well kick this off properly with an actually useful blog post.&lt;/p&gt;
&lt;p&gt;Tune in for the next post, literally gonna start it as soon as I publish this one.&lt;/p&gt;</content><category term="posts"></category><category term="rant"></category></entry><entry><title>Growth</title><link href="https://mazyod.com/blog/2017/08/30/growth/" rel="alternate"></link><published>2017-08-30T14:44:24+00:00</published><updated>2017-08-30T14:44:24+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2017-08-30:/blog/2017/08/30/growth/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;To be honset, I thought I lost it. This flow of inspiration to write. Share an experience, learning or otherwise quite meaningless life story. Somehow, I feel it&amp;rsquo;s back now. After all this time.&lt;/p&gt;
&lt;p&gt;What changed? Hmm .. This could be a separate blog post in of itself! Let …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;To be honset, I thought I lost it. This flow of inspiration to write. Share an experience, learning or otherwise quite meaningless life story. Somehow, I feel it&amp;rsquo;s back now. After all this time.&lt;/p&gt;
&lt;p&gt;What changed? Hmm .. This could be a separate blog post in of itself! Let&amp;rsquo;s just say I had a turning point last week, which lead to an extremely wide range of results, as an affect of a single action from someone can really influence you in the most bizzare ways&amp;hellip;&lt;/p&gt;
&lt;p&gt;Well, this blog post is mostly gonna be about what I&amp;rsquo;ve been up to at work, and how much growth I&amp;rsquo;ve went through in a seemingly short period of time..&lt;/p&gt;
&lt;h2&gt;It&amp;rsquo;s The Little Things&lt;/h2&gt;
&lt;p&gt;Seemingly small changes can have a profound impact on productivity. My latest proof is &lt;a href="https://github.com/tonsky/FiraCode"&gt;FiraCode&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Starting to use this font has made code &lt;strong&gt;much&lt;/strong&gt; nicer too gaze at. As much as I &amp;ldquo;hated&amp;rdquo; operator overloading, it has become rather acceptable with the new symbols this font introduce. &lt;code&gt;~=&lt;/code&gt;, &lt;code&gt;|&amp;gt;&lt;/code&gt;, &lt;code&gt;-&amp;gt;&lt;/code&gt;, &amp;hellip; etc, all these look much more natural and nicer on the eyes as well.&lt;/p&gt;
&lt;p&gt;After learning about this font, I was sitting in a coffee shop trying to solve a rather annoying problem. How can I structure the networking library tests, to encourage developers to quickly and easily write tests for their new endpoints?&lt;/p&gt;
&lt;p&gt;My immediate inclination was to introduce a custom &lt;code&gt;XCTAssert&lt;/code&gt;. That would lead to duplication, since I what I was thinking was something in the lines of:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// asserts each property separately&lt;/span&gt;
&lt;span class="n"&gt;XCTAssertEndpointURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;http://mazyod.com&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;XCTAssertEndpointMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However .. I realized I should probably just implement &lt;code&gt;Equatable&lt;/code&gt; protocol on &lt;code&gt;Endpoint&lt;/code&gt; at this point and assert against &lt;code&gt;expectedEndpoint&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// filling up the endpoint struct is tedious!!&lt;/span&gt;
&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;expectedEndpoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Endpoint&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;expectedEndpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;baseUrl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;expectedEndpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;expectedEndpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;modifiers&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;Yeah, it was as tedious as hell. After taking a look at the &lt;code&gt;Endpoint&lt;/code&gt; objects we are building, I realized, as a tester, I want to quickly just verify the end result is somewhat appropriate. So .. I ended up adding a custom &lt;code&gt;EndpointData&lt;/code&gt; helper class in the tests target, which works something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// FiraCode shines here!&lt;/span&gt;
&lt;span class="n"&gt;XCTAssert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt; &lt;span class="o"&gt;~=&lt;/span&gt; &lt;span class="n"&gt;EndpointData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;https://testing.com/path?query=yes&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&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;post&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                                   &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;assert-this&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;ignores rest&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                                   &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;optionalBody&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This network endpoint testing deserves it&amp;rsquo;s own post, but for the sake of this scope, here is where FiraCode sneaks in. This relationship between the two classes isn&amp;rsquo;t equality, but we still want to match them &amp;hellip; Kinda like regex &amp;hellip; Which is usually annotated as &lt;code&gt;~=&lt;/code&gt; in many languages &amp;hellip; Hence, this.&lt;/p&gt;
&lt;h2&gt;Native Reaction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve had to invest a lot of time and work on packing a react native component into an ObjC framework to be shipped with a fully native app. The process is not trivial, and for the uninitiated, borderline impossible.&lt;/p&gt;
&lt;p&gt;The way ReactNative generates its projects is extremely annoying, since it creates an Xcode project, that depend on other Xcode projects in the &lt;code&gt;nodule_modules&lt;/code&gt; directory. At this point, you&amp;rsquo;re involving &lt;code&gt;yarn&lt;/code&gt; into your Xcode build process, which isn&amp;rsquo;t neat at all.&lt;/p&gt;
&lt;p&gt;Besides that, the team is using &lt;code&gt;create-react-native-app&lt;/code&gt; project, which requires ejecting before packaging .. Ejection process is &lt;a href="https://github.com/react-community/create-react-native-app/pull/346"&gt;interactive, as of yet&lt;/a&gt;. This adds an annoying manual step in the build process.&lt;/p&gt;
&lt;p&gt;Besides all the RN stuff, building ObjC frameworks is just super annoying, with all the header tweaking, architecture lipo-ing, and namespacing crap.&lt;/p&gt;
&lt;h2&gt;I Shall Cast a Spell On You&lt;/h2&gt;
&lt;p&gt;Last but not least to cover this week &amp;hellip; &lt;a href="https://github.com/krzysztofzablocki/Sourcery"&gt;Sourcery&lt;/a&gt;! After contributing to Swiftlint, I really loved how they were using sourcery to generate the linux tests counterparts. That involved no extra work from the developer side, and was integrated as part of the of the build process.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve worked many times on generating code before, but this stencil-based templating just make things way easier than writing a custom Python script each and everytime that traverses stuff in certain ways and relies on a format-based templates.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t, and probably won&amp;rsquo;t, be using Sourcery for the &lt;code&gt;Equatable&lt;/code&gt; and other protocols it demos, but certainly for other neat automations, such generating ObjC compatible bridge for generics and other Swift only types.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I am liking my new job, 6 months in now! Hopefully, can focus more in the upcoming days on leveraging automation and cleansing the project further from tedious typing and legacy &amp;hellip; What can I say, it&amp;rsquo;s a hobby for me.&lt;/p&gt;</content><category term="posts"></category><category term="rant"></category></entry><entry><title>ReactNative as a Framework</title><link href="https://mazyod.com/blog/2017/08/05/reactnative-as-a-framework/" rel="alternate"></link><published>2017-08-05T18:46:15+00:00</published><updated>2017-08-05T18:46:15+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2017-08-05:/blog/2017/08/05/reactnative-as-a-framework/</id><summary type="html">&lt;p&gt;It has been a while since I have posted anything, and to be honest, I shouldn&amp;rsquo;t be posting anything, since I&amp;rsquo;ve got loads of other things to worry about..! But oh well, I have searched the Internets high and wide for tids and bits about packaging ReactNative as …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It has been a while since I have posted anything, and to be honest, I shouldn&amp;rsquo;t be posting anything, since I&amp;rsquo;ve got loads of other things to worry about..! But oh well, I have searched the Internets high and wide for tids and bits about packaging ReactNative as an iOS framework, and couldn&amp;rsquo;t find anything useful&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, here I am saying that &lt;strong&gt;it is indeed possible&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t have the luxury to post a whole tutorial with pics and kitten gifs about the topic, but just enough time to brag- ehm, I mean &lt;em&gt;share&lt;/em&gt; some of the details of how it&amp;rsquo;s possible.&lt;/p&gt;
&lt;p&gt;To those of you who catch up quickly, and are just here for reassurance:&lt;/p&gt;
&lt;p&gt;Simply, create a Framework target in the generated Xcode project, and make the settings and code identical to the app target already created by RN. Done.&lt;/p&gt;
&lt;p&gt;For the rest of us, please follow along as I try to recall all the steps required to perform such a feat.&lt;/p&gt;
&lt;h3&gt;Packaging RN&lt;/h3&gt;
&lt;p&gt;So, for the purpose of this post, you might wanna give it a shot on the side, and not directly apply the changes to your main project .. Just in case the Xcode project catches fire or something&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, &lt;code&gt;react-native init PackagingReact&lt;/code&gt; in terminal should give you a nice, clean RN project to experiment with. I&amp;rsquo;m using the following versions of RN:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;react-native 0.47.1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;react-native-cli 2.0.1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Simply, open the Xcode project residing in the newly created project, and observe in Xcode, under the targets panel, there should be an Application target &lt;code&gt;PackagingReact&lt;/code&gt;, and some other stuff like testing and what not.&lt;/p&gt;
&lt;p&gt;We simply need to do &lt;code&gt;new&lt;/code&gt;, &lt;code&gt;Target...&lt;/code&gt;, and choose &lt;code&gt;dynamic Framework&lt;/code&gt;. I have tried for a few minutes to make it work for &lt;code&gt;static library&lt;/code&gt; target, but that was horrible since we need to bundle some resources and other dependencies&amp;hellip;&lt;/p&gt;
&lt;p&gt;With the Framework target created, you can select it now under the targets panel where the application target was, and start replicating the settings from the application target onto the Framework target. As far as I recall, I had to do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Link the 11 static libraries&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;other linker flags: -ObjC -lc++&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Replicate the custom &lt;code&gt;Run script&lt;/code&gt; phase to the Framework target&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;react-native bundle ...&lt;/code&gt; command to generate &lt;code&gt;main.jsbundle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;main.jsbundle&lt;/code&gt; to the framework target&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s about it, folks. Once that was done, I simply copied over the ObjC code from the application target, to a new class in the Framework, modified that code a bit to load the &lt;code&gt;main.jsbundle&lt;/code&gt; instead of searching for the packager, and voala. Works like a charm.&lt;/p&gt;
&lt;h3&gt;Final Remarks&lt;/h3&gt;
&lt;p&gt;I am now gonna test to see if I can make the framework target Swift based (no reason it can&amp;rsquo;t be). After that, I would like to automate this process, so it becomes a single click deployment of the RN application to an iOS framework (which we can possibly link using Carthage even).&lt;/p&gt;</content><category term="devlog"></category><category term="null"></category></entry><entry><title>Shipping the Game</title><link href="https://mazyod.com/blog/2017/02/25/shipping-the-game/" rel="alternate"></link><published>2017-02-25T22:41:48+00:00</published><updated>2017-02-25T22:41:48+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2017-02-25:/blog/2017/02/25/shipping-the-game/</id><summary type="html">&lt;p&gt;OMG, I STILL CAN&amp;rsquo;T GET OVER THE FACT THAT I&amp;rsquo;VE SHIPPED MY GAME!&lt;/p&gt;
&lt;p&gt;Yeah, it&amp;rsquo;s that crazy .. When you&amp;rsquo;ve obsessed over a project for 5+ years, and it finally crosses the finish line .. I mean .. It&amp;rsquo;s probably like losing your leg for 5 years, then …&lt;/p&gt;</summary><content type="html">&lt;p&gt;OMG, I STILL CAN&amp;rsquo;T GET OVER THE FACT THAT I&amp;rsquo;VE SHIPPED MY GAME!&lt;/p&gt;
&lt;p&gt;Yeah, it&amp;rsquo;s that crazy .. When you&amp;rsquo;ve obsessed over a project for 5+ years, and it finally crosses the finish line .. I mean .. It&amp;rsquo;s probably like losing your leg for 5 years, then waking up one day and it&amp;rsquo;s there! Then, even though you&amp;rsquo;re absolutely delighted at first, you keep getting these episodes of pure delight for overcoming such a stigma &amp;hellip;&lt;/p&gt;
&lt;h3&gt;Wasn&amp;rsquo;t It Fun?&lt;/h3&gt;
&lt;p&gt;So, you&amp;rsquo;re probably asking yourself by now.. &amp;ldquo;Wait, you were building a freaking game! Which you loved! Wasn&amp;rsquo;t it fun?!?!&amp;rdquo; &amp;hellip; Yeah, sure when I was writing code and designing solutions it was liberating .. But then, most of my off time during work or burnout period, it was just a depressing feeling to think about it.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t believe me? Ask anyone who was foolish enough to ask me, &amp;ldquo;So, how is the game going?&amp;rdquo; or &amp;ldquo;When are you planning to ship?&amp;rdquo;. One of my friends who did ask me this question regularly, said to his other friend, and I quote: &amp;ldquo;Everytime I ask [Maz] about the game, I see the expression on his face shift immediately&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;That wasn&amp;rsquo;t fun. Feeling pressured to ship after so long, not being able to see the finish line, skill level not matching the challenges at hand &amp;hellip; Check the image below, and I need not say more.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Skill level vs Challenge level chart" src="/images/challenge_vs_skill.jpg"&gt;&lt;/p&gt;
&lt;h3&gt;What Are the Implications?&lt;/h3&gt;
&lt;p&gt;In 2014, I worked at a startup in Dubai as an iOS developer with a decent team and salary. I&amp;rsquo;m now working in Dubai as an iOS developer with a decent team and salary. The difference? Before shipping, and after&amp;hellip; Perhaps you can&amp;rsquo;t attribute the difference fully to the shipping of the game, but I sure feel it has lots to do with it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2014&lt;/strong&gt;: I brooded over the thought of studying Japanese.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2017&lt;/strong&gt;: I enrolled before settling in, and already enjoying the classes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2014&lt;/strong&gt;: I&amp;rsquo;ve attempted to buy a car, apartment, and make big decisions, but failed to execute anything.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2017&lt;/strong&gt;: I&amp;rsquo;ve got a new job + relocation, car, and apartment in 3 months. Also, I feel prepared to take the biggest step in an adult&amp;rsquo;s life.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2014&lt;/strong&gt;: I indulged in mindless refactoring at work with low biz value.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2017&lt;/strong&gt;: I&amp;rsquo;m proposing and pushing structural changes from day one.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2014&lt;/strong&gt;: I lacked the confidence at work, home, and in social gatherings.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2017&lt;/strong&gt;: I&amp;rsquo;m much more content with how my relationships turn out.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2014&lt;/strong&gt;: One small external emotional impact could leave me broken for weeks.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2017&lt;/strong&gt;: It barely takes more than a few minutes to get over something.. After all, I shipped &lt;a href="http://level3.io/"&gt;DAMA&lt;/a&gt;! XD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I hope my point became clear with the examples above. I am not really sure if my game was a stigma in the past that pulled me back, but at least I&amp;rsquo;m certain now that it&amp;rsquo;s a source of pride and confidence.&lt;/p&gt;
&lt;h3&gt;So, You&amp;rsquo;re a Success Now?&lt;/h3&gt;
&lt;p&gt;Nope. Not yet. And here is where the essence of this whole post comes in:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You must find your contentment within yourself.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Only one of all my friends and family &lt;em&gt;truly&lt;/em&gt; came close to understanding what finally shipping my game meant to me. &lt;em&gt;Only one!&lt;/em&gt;. It wasn&amp;rsquo;t like I could share this accomplishment with people, and amplify the outcome, so to speak.&lt;/p&gt;
&lt;p&gt;Also, the game itself wasn&amp;rsquo;t a huge hit. If anything, I&amp;rsquo;ve only lost sales so far and accumulated running costs from the servers and other services, lol. But that doesn&amp;rsquo;t matter, either!&lt;/p&gt;
&lt;p&gt;This brings us back to the quote above, and that is: I was aware this milestone only meant a tremendous amount to me, and no one else. People didn&amp;rsquo;t like it? Meh. People thought I wasted 5 years of my life? Meh. What do they know?&lt;/p&gt;
&lt;h3&gt;Bonus: But You&amp;rsquo;ve Abandoned the Blog!&lt;/h3&gt;
&lt;p&gt;Some may point out that the blog was one of my &amp;ldquo;biggest&amp;rdquo; accomplishments during my pre-shipping, and it didn&amp;rsquo;t come back, yet. Actually, this is an excellent point, and it has to do with the actual value this blog had! Try reading the posts, and you&amp;rsquo;ll realize what a mess 90% of it was.&lt;/p&gt;
&lt;p&gt;No proper structure, barely any useful content, and when it was finally there at a good level, it was really just me scraping for any remnants of self-dignity and busywork to make me feel productive so that I could muster some motivation to keep moving forward.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m super glad that I&amp;rsquo;ve seen my game through, and I wouldn&amp;rsquo;t change anything if I would go back in time. It wasn&amp;rsquo;t about the actual game; it was about the learnings and the journey.&lt;/p&gt;</content><category term="posts"></category><category term="dama"></category></entry><entry><title>Let's Encrypt Phoenix!</title><link href="https://mazyod.com/blog/2016/12/19/lets-encrypt-phoenix/" rel="alternate"></link><published>2016-12-19T18:53:02+00:00</published><updated>2016-12-19T18:53:02+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-12-19:/blog/2016/12/19/lets-encrypt-phoenix/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;After a previous post outlining the importance of using SSL, especially when dealing with websockets, I needed now to implement auto-renewing certificates as a cron job or whatever.&lt;/p&gt;
&lt;p&gt;Previously, I had used the &amp;ldquo;standalone&amp;rdquo; approach to get my certs, which worked great.. However, it&amp;rsquo;s not ideal when you …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;After a previous post outlining the importance of using SSL, especially when dealing with websockets, I needed now to implement auto-renewing certificates as a cron job or whatever.&lt;/p&gt;
&lt;p&gt;Previously, I had used the &amp;ldquo;standalone&amp;rdquo; approach to get my certs, which worked great.. However, it&amp;rsquo;s not ideal when you want to keep your server running during the renewal process! You see, the standalone server needs to bind to port 80/443, but the running server already occupies those ports.&lt;/p&gt;
&lt;h2&gt;The Root of Groot&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Root of Groot" src="http://i.imgur.com/Te9RTcn.png"&gt;&lt;/p&gt;
&lt;p&gt;Actually, I wanna talk about Webroot, a certbot plugin that allows you to verify your domain through an existing web server.&lt;/p&gt;
&lt;p&gt;So, the way webroot works is it basically writes the authentication files to a path you specify, and then attempts to request that file for the authentication process.&lt;/p&gt;
&lt;p&gt;Sounds awesome, right! Just write your files to &lt;code&gt;priv/static&lt;/code&gt;, and we&amp;rsquo;re golden! .. Not. Even though I tested creating files in that directory, then requesting them using curl, and it worked.. This approach didn&amp;rsquo;t work in production. I believe it has to do with the code reloader.&lt;/p&gt;
&lt;p&gt;After much dabbling around with the production server, I finally realized that the actual server is running in the &lt;code&gt;_build&lt;/code&gt; folder! Simply changing &lt;code&gt;priv/static&lt;/code&gt; to &lt;code&gt;_build/prod/lib/app/priv/static&lt;/code&gt; finally did the trick..&lt;/p&gt;
&lt;h2&gt;The Steps&lt;/h2&gt;
&lt;p&gt;So, to get webroot working with your phoenix server, first change your &lt;code&gt;cli.ini&lt;/code&gt; configuration like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;rsa-key-size&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;4096&lt;/span&gt;
&lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;me@example.com&lt;/span&gt;
&lt;span class="c1"&gt;# disabled for renew: domains = my.domain.com&lt;/span&gt;
&lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;True&lt;/span&gt;
&lt;span class="na"&gt;authenticator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;webroot&lt;/span&gt;
&lt;span class="na"&gt;webroot-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;/path/to/project/_build/prod/lib/myapp/priv/static&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Please take note above of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We disable the domains options since it upsets the renewal process. Uncomment if you are generating for the first time.&lt;/li&gt;
&lt;li&gt;Make sure to set your email.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you do that, you can proceed with running the certbot program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;./certbot-auto&lt;span class="w"&gt; &lt;/span&gt;renew&lt;span class="w"&gt; &lt;/span&gt;--dry-run
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I felt inclined to donate to EFF for their fantastic work on let&amp;rsquo;s encrypt, and so feel inclined to promote them here as well:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://supporters.eff.org/donate/support-work-on-certbot"&gt;Donate to EFF&lt;/a&gt;&lt;/p&gt;</content><category term="posts"></category><category term="phoenix"></category></entry><entry><title>Useful Unity Assets</title><link href="https://mazyod.com/blog/2016/12/10/useful-unity-assets/" rel="alternate"></link><published>2016-12-10T21:49:46+00:00</published><updated>2016-12-10T21:49:46+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-12-10:/blog/2016/12/10/useful-unity-assets/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As I wait for my laptop battery to drain so I can do complete power cycle for the battery, might as well write a post!&lt;/p&gt;
&lt;p&gt;I recently started digging through the Unity Asset Store, and found some gems of assets! Let&amp;rsquo;s take a look.&lt;/p&gt;
&lt;h2&gt;Moderation&lt;/h2&gt;
&lt;p&gt;Before I go …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As I wait for my laptop battery to drain so I can do complete power cycle for the battery, might as well write a post!&lt;/p&gt;
&lt;p&gt;I recently started digging through the Unity Asset Store, and found some gems of assets! Let&amp;rsquo;s take a look.&lt;/p&gt;
&lt;h2&gt;Moderation&lt;/h2&gt;
&lt;p&gt;Before I go into this, let me say this: &lt;strong&gt;Moderation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pulling every asset store package to &amp;ldquo;speed up&amp;rdquo; your development process would be a fatal mistake. A lot of assets out there will actually do more harm than good. So, let&amp;rsquo;s first take a look at which assets are OK to use:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Battle-Tested&lt;/strong&gt;: The asset must have 4.5+ rating, and reviewed by a reasonable number of users, with insightful reviews.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Focused&lt;/strong&gt;: The asset must solve a specific problem, and does it well, instead of advertising that it solves &lt;em&gt;everything&lt;/em&gt; for you.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docs &amp;amp; Features&lt;/strong&gt;: Make sure their docs are readable so you can actually use it! Also, it supports the build configurations you need.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With that being said, here is my list sorted from my favorite, all the way down to the least preferred. However, I use them all, so they&amp;rsquo;re all great!&lt;/p&gt;
&lt;h4&gt;Json.NET&lt;/h4&gt;
&lt;p&gt;This one gave me a true piece of mind with so little done on my end. Basically, I was using Newtonsoft.Json in my game, and it was breaking under certain conditions in different build configurations. I would have to spend days testing and making sure I work around all the issues!&lt;/p&gt;
&lt;p&gt;Thankfully, I found this neat fellow! It has the exact same namespace and APIs as Newtonsoft.Json, so all I did was nuke the open-source version and import this one from the asset store, and just like that&amp;hellip; All errors begone!&lt;/p&gt;
&lt;p&gt;I love it the most because it solves a super specific problem, JSON serialization, in a super efficient and straight-forward manner.&lt;/p&gt;
&lt;h4&gt;I2Localization&lt;/h4&gt;
&lt;p&gt;As I was losing my mind managing localized strings, trying to solve Arabic RTL issues with NGUI, I stopped everything and started doing some research. How do people deal with this issue?&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s when I found I2Localization. It boasts RTL support, and with a little bit of a setup, it syncs with Google docs right from the Unity editor! Another super useful feature is statically typed localized strings, using the helper scripts that ship with this asset.&lt;/p&gt;
&lt;p&gt;I had some issues with RTL initially, but I quickly added a fix, and submitted a report to their forums. They were fast to respond with confirmation of the bug and shipping a fix soon after.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s also kind of unfortunate how they don&amp;rsquo;t support multi-line RTL 100%, but it works for my current needs, so meh. Ultimately, I would really recommend this for the Google docs syncing and statically typed strings alone!&lt;/p&gt;
&lt;h4&gt;BestHTTP&lt;/h4&gt;
&lt;p&gt;This is the last one I want to mention, which ironically, is what I need the most. I don&amp;rsquo;t love it as much as the ones before, but I needed it so badly, that I have to overlook its issues.&lt;/p&gt;
&lt;p&gt;BestHTTP is simply the best HTTP experience you can have in a cross-platform Unity game. I say cross platform because, if it was for one platform, I&amp;rsquo;d personally prefer to use native networking capabilities instead. Alas, my game is cross platform.&lt;/p&gt;
&lt;p&gt;The HTTP request APIs are 100x better than the stupid &lt;code&gt;WWW&lt;/code&gt; thingie Unity provides us. The recent &lt;code&gt;UnityWebRequest&lt;/code&gt; is even worse in terms of stability! So, I use this library for &lt;code&gt;GET&lt;/code&gt;/&lt;code&gt;POST&lt;/code&gt; HTTP requests, and it really delivers the thing you need.&lt;/p&gt;
&lt;p&gt;The main reason I got it, however, is the websocket feature it has. It&amp;rsquo;s a well written/maintained websocket implementation, with main thread callbacks, very detailed logging and error handling that helps you crack down the nastiest of issues. The next best thing I found that provides websockets was an outdated websocket-sharp package from 2014, which worked surprisingly OK, but I just did trust it..&lt;/p&gt;
&lt;p&gt;The only reason this isn&amp;rsquo;t on the top of the list is the way it synchronizes callbacks to the main thread. It uses a MonoBehaviour, which uses mutex to check for updates &lt;strong&gt;on update&lt;/strong&gt;! Like, why?! I don&amp;rsquo;t need to check HTTP results 60 times a second. There should be a better way using semaphores or similar to only trigger updates when needed.&lt;/p&gt;
&lt;p&gt;All in all, this library is great, and you should get it if you need serious HTTP functionality or websockets.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;My laptop is out of battery! Time to shut it down.&lt;/p&gt;</content><category term="posts"></category><category term="unity"></category></entry><entry><title>A Sockety Tale</title><link href="https://mazyod.com/blog/2016/12/10/a-sockety-tale/" rel="alternate"></link><published>2016-12-10T14:16:51+00:00</published><updated>2016-12-10T14:16:51+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-12-10:/blog/2016/12/10/a-sockety-tale/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;On a fine Friday evening, after I went over my git repos making sure everything is synced with upstream, I delightfully pack up reminiscing the past week. It was a fine, productive week! Lots of trello cards moved over to the done column.&lt;/p&gt;
&lt;p&gt;As my phone&amp;rsquo;s slack was …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;On a fine Friday evening, after I went over my git repos making sure everything is synced with upstream, I delightfully pack up reminiscing the past week. It was a fine, productive week! Lots of trello cards moved over to the done column.&lt;/p&gt;
&lt;p&gt;As my phone&amp;rsquo;s slack was pinging, alerting me of the status of Unity cloud builds, I got an idea. Why not download a build on my Android and try it out on the way home? The bots server was already running, so they&amp;rsquo;ll keep me company.&lt;/p&gt;
&lt;p&gt;As I started strolling back home, I downloaded the app, installed it, and started using it&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Let the Debugging Begin!&lt;/h2&gt;
&lt;h3&gt;Portable Debugger&lt;/h3&gt;
&lt;p&gt;To my utter horror, the user data was failing to load! I restarted the app, tried several retry buttons; alas, nothing seemed to work.&lt;/p&gt;
&lt;p&gt;At this point, I usually despair at my future demise, as I had to hook up the device to a debugger to figure out what&amp;rsquo;s going on &amp;hellip; However, as part of this productive week, I had hooked up a remote logger!&lt;/p&gt;
&lt;p&gt;So, as I am still making my way back home, I launch the online console and immediately welcomed with a wall of logs so granular, they looked like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[...]:  [DEBUG]: Logger initialized...
[...]:  [DEBUG]: [HTTPConnection]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Connecting to dama.level3.io:80
[...]:  [INFO]: [HTTPConnection]: Connected to dama.level3.io:80
[...]:  [INFO]: [HTTPRequest]: Sending request: &amp;#39;GET /socket/websocket?token=... HTTP/1.1&amp;#39;
[...]:  [INFO]: [HTTPRequest]: &amp;#39;GET /socket/websocket?token=... HTTP/1.1&amp;#39; sent out
[...]:  [DEBUG]: [HTTPConnection]: ws://dama.level3.io:80/socket/websocket?token=... - Receive - protocol: WebSocket
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Receive. forceReadRawContentLength: &amp;#39;-1&amp;#39;, readPayloadData: &amp;#39;True&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Status Line: &amp;#39;HTTP/1.1&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - HTTP Version: &amp;#39;1.1&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Status Code: &amp;#39;400&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Status Message: &amp;#39;Bad Request&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Header - &amp;#39;Server&amp;#39;: &amp;#39;Cowboy&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Header - &amp;#39;Date&amp;#39;: &amp;#39;Fri, 09 [...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Header - &amp;#39;Content-Length&amp;#39;: &amp;#39;0&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - Header - &amp;#39;Connection&amp;#39;: &amp;#39;keep-alive&amp;#39;
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - ReadRaw - contentLength: 0
[...]:  [DEBUG]: [HTTPResponse]: &amp;#39;ws://dama.level3.io:80/socket/websocket?token=...&amp;#39; - ReadPayload Finished!
[...]:  [DEBUG]: [HTTPConnection]: ws://dama.level3.io:80/socket/websocket?token=... - Receive - Finished Successfully!
[...]:  [INFO]: [phx][socket]: Request Finished Successfully, but the server sent an error. Status Code: 400-Bad Request Message: 
[...]:  [INFO]: Websocket connection error: Request Finished Successfully, but the server sent an error. Status Code: 400-Bad Request Message: 
[...]:  [INFO]: Purchaser: OnInitialized - PASS
[...]:  [WARN]: We are not online
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As I went through the logs, I found the culprit. For whatever reason, I was getting a &lt;code&gt;400 Bad Request&lt;/code&gt; response from my websocket requests. Thankfully, my backend also logs warns and errors to the same console.&lt;/p&gt;
&lt;p&gt;With a few taps, I switch over to the backend logs. Unfortunately, there were no logs whatsoever. That meant, the server wasn&amp;rsquo;t throwing any warnings or errors&amp;hellip;&lt;/p&gt;
&lt;h3&gt;Dive Into the Logs&lt;/h3&gt;
&lt;p&gt;I was getting closer to the apartment, so I started thinking, where can I begin to debug this? The server verbose logs of course!&lt;/p&gt;
&lt;p&gt;So, as soon as I entered the apartment, I took out my laptop and logged into the server to view the logs files. These were configured to log everything, with log rotation in place, it&amp;rsquo;s bound to be useful, right? Nope. Even those logs didn&amp;rsquo;t show me anything of interest about this bad request error!&lt;/p&gt;
&lt;p&gt;Am I stuck at this point? Is it the new HTTP library that I switched to recently? .. Wait, this error never showed up on the Unity Editor, why is it happening on Android? The main difference was really the Internet connection. Android was using a data plan&amp;hellip;&lt;/p&gt;
&lt;p&gt;As I switched my phone over to the apartment WiFi, I prayed silently that the issue would persist and not go away (because how the hell am I suppose to debug an issue with the cellular connection!!). The moment of truth was clear, the issue did &lt;strong&gt;not&lt;/strong&gt; persist! The issue was with a high degree of certainty with the cellular connection.&lt;/p&gt;
&lt;h3&gt;Sysadmin Toolbelt&lt;/h3&gt;
&lt;p&gt;Now that I was certain the issue manifests itself while between the client and the server, I had to take a look from the server side as to what&amp;rsquo;s going on.&lt;/p&gt;
&lt;p&gt;I no longer remember when did I learn about &lt;code&gt;tcpdump&lt;/code&gt;, but I do remember a developer taught me about this tool on some Slack channel. This is definitely the right tool for debugging this insane issue!&lt;/p&gt;
&lt;p&gt;After launching tcpdump for the first time, and seeing it dump thousands of lines of gibberish, I had to first isolate the problem!&lt;/p&gt;
&lt;p&gt;First, I shutdown the bots server, since it was still going strong and generating insane amount of traffic! After that, I wanted &lt;code&gt;tcpdump&lt;/code&gt; to show me legible data about my specific tcp connection. To do that, I used &lt;code&gt;tcpdump&lt;/code&gt; ascii output option, as well as source IP filter option:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;tcpdump -A -i eth0 src 31.4.188.x
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That did it! As I launched my game and connected from the 3G connection, and then the apartment WiFi, the difference was clear&amp;hellip; The headers when connecting through the 3G connection were malformed! Specifically, the &lt;code&gt;Upgrade: websocket&lt;/code&gt; header was missing. How can the server process such a request? Obviously, it couldn&amp;rsquo;t.&lt;/p&gt;
&lt;h3&gt;Our Savior&lt;/h3&gt;
&lt;p&gt;As usual, the real solution is found on StackOverflow. I easily searched for the problem and found the answer. My cellular company were using a proxy in the middle, which counts as a hop, which removes the &lt;code&gt;Upgrade:&lt;/code&gt; header. The solution? Use secure websockets!&lt;/p&gt;
&lt;p&gt;I wanted to secure my server for a while, but it wasn&amp;rsquo;t critical. This time around, I just had to do it for the sake of allowing users across the variety of connections out there to connect.&lt;/p&gt;
&lt;p&gt;Since my server is running on DigitalOcean, it took me less than 10 mins to setup letsencrypt (certbot), generate self-signed certificates, switch phoenix to use https, and push a new build to Unity Cloud Build that uses secure websockets.&lt;/p&gt;
&lt;p&gt;The rejoice came after the cloud builder finished, and I was able to install the new build, and confirm that the issue was resolved! Yay!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;What I really like about this tale is the range of technical knowhow involved in debugging the issue, including rudimentary steps performed on the phone itself!&lt;/p&gt;
&lt;p&gt;Programmers make for great investigators. They live by Sherlock Holmes phrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Once you&amp;rsquo;ve eliminated the impossible, what you&amp;rsquo;re left with, however improbable, is the truth!&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="posts"></category><category term="websocket"></category></entry><entry><title>Tech Buffet</title><link href="https://mazyod.com/blog/2016/12/04/tech-buffet/" rel="alternate"></link><published>2016-12-04T23:45:23+00:00</published><updated>2016-12-04T23:45:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-12-04:/blog/2016/12/04/tech-buffet/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This blog has been side stepped for quite a while .. For some reason, this pattern happens every time.. During the beginning of the year, I&amp;rsquo;m like &amp;ldquo;I&amp;rsquo;ma blog all year!!&amp;rdquo;. However, I slow down during the middle, and near the end realize, &amp;ldquo;Oh crap, let me play …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This blog has been side stepped for quite a while .. For some reason, this pattern happens every time.. During the beginning of the year, I&amp;rsquo;m like &amp;ldquo;I&amp;rsquo;ma blog all year!!&amp;rdquo;. However, I slow down during the middle, and near the end realize, &amp;ldquo;Oh crap, let me play catch up now&amp;rdquo;.&lt;/p&gt;
&lt;h2&gt;All You Can Eat&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t think it was a bad year for the blog, though, all things considered. I&amp;rsquo;ve finally overcome my iOS comfortzone and delved into other interesting fields, like Elixir and Unity.&lt;/p&gt;
&lt;p&gt;I believe I also migrated my app backend to Heroku this year, and started using Heroku a lot more in general. I mean, the main restriction that bothers me is the freaking power cycle, but other than that, I just dump all my servers there.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve indulged in docker during the beginning of the year and realized it was a crazy and unnecessary overhead for an army of one. Then, a friend convinced me to try out docker cloud during the end of the year, which was an amazing experience at first .. Until docker cloud &amp;ldquo;Lost contact with a node&amp;rdquo;&amp;hellip; Seriously? Also their support forums suck. There, I said it.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see, besides that &amp;hellip; &lt;/p&gt;
&lt;p&gt;How about using the new Android Studio external native build feature? Did you know Android studio can freaking import a CMakeLists file into gradle and elegantly build that into a native library, packaged as an AAR?! That was neat.&lt;/p&gt;
&lt;p&gt;Regarding native libraries, docker wasn&amp;rsquo;t a complete loss this year. I&amp;rsquo;ve actually learned about and utilized Dockcross; a set of pre-configured docker images that contain cross-compile toolchains. To build my C lib for linux on my Mac, all I have to do now is &lt;code&gt;./dockcross ./build.sh&lt;/code&gt;. How neat!&lt;/p&gt;
&lt;p&gt;Of course, the best thing that happened this year was meeting Elixir and getting to know it better. Just like a steak, you let it cook steadily, while incrementally applying the right set of spices. By the end of the process, you got yourself quite the indulgent!&lt;/p&gt;
&lt;p&gt;Tech aside, I was really lucky to have worked with a super-fun team over at Bigfootgames.com. They helped my get the ball rolling with my game. I also had the fortune to knowing two super talented guys; a designer and a composer. Their fine work is the main reason I have the energy to keep at making this damn game (no pun intended).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s bring tech back again, since I&amp;rsquo;m not nearly done with that yet. This year we witnessed the drastic change that Firebase went through. Luckily enough, I was able to work on &lt;strong&gt;two&lt;/strong&gt; shipped products that utilize their new services. Firebase is just great; you should take a look at it.&lt;/p&gt;
&lt;p&gt;While we are in this area, might as well mention the insanely useful papertrail logging service. I&amp;rsquo;ve been having issues with logging for a while, and never really cracked the problem until I found Papertrail. They have a neat, UDP based remote syslog setup which is compatible with an abundant number of technologies, including Elixir.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is just a dump, so I do apologize for the lack of structure. I can also summarize my 2016, from the tech side at least, as the year I finally understood Unity.&lt;/p&gt;
&lt;p&gt;Regardless of anything else, Unity was this thing I just couldn&amp;rsquo;t click with. Having committed to learning it, during my escape to Japan, was what will probably last with me the longest. I have arguably spent most of my time in 2016 sleeping, obviously, but second to that, doing Unity related stuff.&lt;/p&gt;
&lt;p&gt;Elixir was fun, but not really the domain of my project. It&amp;rsquo;s the assisting component that I unfortunately had to simply make work, and move on to perfecting the experience in Unity.&lt;/p&gt;
&lt;p&gt;So, that took about 15 mins to write, lol. Says a lot about how long I&amp;rsquo;ve been wanting to dump this stuff&amp;hellip; Would be nice to make it all dumps instead&amp;hellip;&lt;/p&gt;</content><category term="posts"></category><category term="blog"></category><category term="rant"></category></entry><entry><title>Unity Ads</title><link href="https://mazyod.com/blog/2016/11/13/unity-ads/" rel="alternate"></link><published>2016-11-13T11:14:08+00:00</published><updated>2016-11-13T11:14:08+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-11-13:/blog/2016/11/13/unity-ads/</id><summary type="html">&lt;p&gt;Unity ads is a great opportunity for games to make some serious revenue from the free players segment. These players would never pay a single dime, so making them watch a video ad results in revenue for your game.&lt;/p&gt;
&lt;p&gt;The Unity platform is insanely good with video ads. Basically, you …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Unity ads is a great opportunity for games to make some serious revenue from the free players segment. These players would never pay a single dime, so making them watch a video ad results in revenue for your game.&lt;/p&gt;
&lt;p&gt;The Unity platform is insanely good with video ads. Basically, you click a few buttons in unity, add &lt;code&gt;Advertisement.Show();&lt;/code&gt;, and your done.&lt;/p&gt;
&lt;p&gt;This is all nice and dandy until you realize that you need to now reward the user for watching the ad. The ad runs on the client, so it might be compromised .. Unity solves this problem as well by providing Server-to-Server callbacks.&lt;/p&gt;
&lt;p&gt;So, basically, once a user watches an ad, Unity servers send a callback to your server with the user id that confirms that action. You can then be sure that the user can be awarded the promised reward without worrying about it being compromised.&lt;/p&gt;
&lt;p&gt;The only issue here is that implementing backend callbacks is a chore, and I don&amp;rsquo;t think enough players will bother hacking the app. On the other hand, adding the reward system within the client is just too risky &amp;hellip;&lt;/p&gt;
&lt;p&gt;While throwing my thoughts here it occurred to me that I can implement the server callbacks not mainly to prevent hacking, but &lt;strong&gt;mainly&lt;/strong&gt; to make the implementation easier. With the callback sent to my server, I can simply update the profile, and push that update to the client.&lt;/p&gt;</content><category term="devlog"></category><category term="null"></category></entry><entry><title>on second thought</title><link href="https://mazyod.com/blog/2016/09/27/on-second-thought/" rel="alternate"></link><published>2016-09-27T15:59:32+00:00</published><updated>2016-09-27T15:59:32+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-09-27:/blog/2016/09/27/on-second-thought/</id><summary type="html">&lt;p&gt;Well, I did need to write about the current authentication design, not that I think it&amp;rsquo;s amazing or anything like that, but in fact, I need to write it out in order to properly think about it.&lt;/p&gt;
&lt;p&gt;So, what&amp;rsquo;s the deal with the authentication flow?&lt;/p&gt;
&lt;p&gt;So, I decided …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Well, I did need to write about the current authentication design, not that I think it&amp;rsquo;s amazing or anything like that, but in fact, I need to write it out in order to properly think about it.&lt;/p&gt;
&lt;p&gt;So, what&amp;rsquo;s the deal with the authentication flow?&lt;/p&gt;
&lt;p&gt;So, I decided to go with a pretty &amp;ldquo;novel&amp;rdquo; approach for authentication, and that is to redirect the user to a website that (s)he can then authenticate through, which &amp;ldquo;upgrades&amp;rdquo; the associated account&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, everytime a user installs the app, a new &amp;ldquo;guest&amp;rdquo; account is created, and a device token is associated with that account. The device token, as the name suggests, is a unique auth token for that device, which provides access to the account without the need to enter the username/password everytime. Pretty basic stuff..&lt;/p&gt;
&lt;p&gt;Now, once the user logs in on the web portal, as I call it, the device needs to &amp;ldquo;know&amp;rdquo; about this authentication process, and change the initial guest account to the new logged in account.&lt;/p&gt;
&lt;p&gt;My approach to this problem was to send the guest auth token with url redirect. I am not worried about the security of this token, since it is &lt;strong&gt;always&lt;/strong&gt; a token of the guest account, which isn&amp;rsquo;t significant.&lt;/p&gt;
&lt;p&gt;So, once the user is on the login portal with that token, we can fetch the guest account and prepare for the upgrade process. If the auth process succeeds, there will be a new account we want to &amp;ldquo;migrate&amp;rdquo; to&amp;hellip;&lt;/p&gt;
&lt;p&gt;I am thinking of simply migrating the device token to that account, and once the user is back in the game, we detect the token and that it has been migrated, and send an updated token of the new account, which is then securely stored on the device for further operations.&lt;/p&gt;
&lt;p&gt;Everytime I think about it or try to find issues with this approach, I don&amp;rsquo;t see anything wrong, but also every &amp;ldquo;new&amp;rdquo; design you come up with in programming will always make you anxious since if this is so great, why isn&amp;rsquo;t everyone using it?&lt;/p&gt;
&lt;p&gt;Well, I don&amp;rsquo;t have time to care about that, I need to get done with this&amp;hellip;&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>i forgot about this</title><link href="https://mazyod.com/blog/2016/09/27/i-forgot-about-this/" rel="alternate"></link><published>2016-09-27T15:55:47+00:00</published><updated>2016-09-27T15:55:47+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-09-27:/blog/2016/09/27/i-forgot-about-this/</id><summary type="html">&lt;p&gt;Holy crap, I completely forgot about this devlog &lt;code&gt;&amp;gt;__&amp;lt;&lt;/code&gt; .. definitely should not have&amp;hellip;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t remember what the last post was about, but since then, just too many things were worthy of at least dumping here .. Learning new optimization tricks in python thanks to the interview process preparations, Swift …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Holy crap, I completely forgot about this devlog &lt;code&gt;&amp;gt;__&amp;lt;&lt;/code&gt; .. definitely should not have&amp;hellip;&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t remember what the last post was about, but since then, just too many things were worthy of at least dumping here .. Learning new optimization tricks in python thanks to the interview process preparations, Swift 3 changes, Phoenix controllers and HTML forms, and of course, the ordeal with ecto.&lt;/p&gt;
&lt;p&gt;Well, I don&amp;rsquo;t feel like writing anymore for now, but should revisit this once something comes up.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>Changeset</title><link href="https://mazyod.com/blog/2016/08/12/changeset/" rel="alternate"></link><published>2016-08-12T14:59:05+00:00</published><updated>2016-08-12T14:59:05+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-12:/blog/2016/08/12/changeset/</id><summary type="html">&lt;p&gt;That was painful &amp;hellip; Dealing with Ecto changesets.&lt;/p&gt;
&lt;p&gt;The thing is, I&amp;rsquo;ve been trying to implement a way to use changesets in order to protect certain properties of the model from being modified by an external source. For example, users of the app can change their username, but not their …&lt;/p&gt;</summary><content type="html">&lt;p&gt;That was painful &amp;hellip; Dealing with Ecto changesets.&lt;/p&gt;
&lt;p&gt;The thing is, I&amp;rsquo;ve been trying to implement a way to use changesets in order to protect certain properties of the model from being modified by an external source. For example, users of the app can change their username, but not their rating.&lt;/p&gt;
&lt;p&gt;To achieve something like that, I first created &lt;code&gt;external_changeset&lt;/code&gt; on the &lt;code&gt;user&lt;/code&gt; model:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;external_changeset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Given the user, and the proposed parameters to be changed, we should return a changeset with the following conditions:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The changes shouldn&amp;rsquo;t modify protected members&lt;/li&gt;
&lt;li&gt;The changes shouldn&amp;rsquo;t render the model in an invalid state (e.g. empty username)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Well, I thought it was simple at first, because I&amp;rsquo;ve seen the &lt;code&gt;cast&lt;/code&gt; method in action. &lt;code&gt;cast&lt;/code&gt; is a method on &lt;code&gt;Ecto.Changeset&lt;/code&gt; that allows you to control the changes in a certain way&amp;hellip;&lt;/p&gt;
&lt;p&gt;The thing is, I&amp;rsquo;ve always thought that the rules you pass into the &lt;code&gt;cast&lt;/code&gt; method are applied to the &lt;code&gt;Ecto.Changeset&lt;/code&gt; model itself, but no! The rules are actually applied to the final resulting model! What does that mean?&lt;/p&gt;
&lt;p&gt;Well, first, let&amp;rsquo;s see what the &lt;code&gt;cast&lt;/code&gt; method does:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;mazyod&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="sx"&gt;~w(username email)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Depending on whether you are on the latest ecto release or not, cast takes the model or changeset as the first parameter, then the changes as a map, then an enumerable of fields that are required or can be modified.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s where my earlier statement comes into play. Notice how even though we &amp;ldquo;require&amp;rdquo; an email field, the changes map doesn&amp;rsquo;t have an email. That&amp;rsquo;s fine, because if the user object itself has the email set, that means the overall changeset is still valid!&lt;/p&gt;
&lt;p&gt;Phew! I needed to write all that out, since I am sure my future self will need it.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>Doing Yoga with C#</title><link href="https://mazyod.com/blog/2016/08/08/doing-yoga-with-c/" rel="alternate"></link><published>2016-08-08T16:17:02+00:00</published><updated>2016-08-08T16:17:02+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-08:/blog/2016/08/08/doing-yoga-with-c/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Throughout my game development journey with Unity + C#, I have found the C# language extremely flexible and versatile. By utilizing the right techniques, one could eliminate lots of boiler plate and achieve remarkable expressiveness.&lt;/p&gt;
&lt;p&gt;I talk about expressive code a lot in my posts, but if you need a …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Throughout my game development journey with Unity + C#, I have found the C# language extremely flexible and versatile. By utilizing the right techniques, one could eliminate lots of boiler plate and achieve remarkable expressiveness.&lt;/p&gt;
&lt;p&gt;I talk about expressive code a lot in my posts, but if you need a refresher, expressive code is simply doing more stuff with less code. I would like to shed some light on two use cases today, both of which utilize generics to achieve their expressive nature.&lt;/p&gt;
&lt;h2&gt;Event System&lt;/h2&gt;
&lt;p&gt;An event system, observer patter, publish-subscribe .. etc, is a very basic design that is mostly needed in any type of software system. It helps you achieve decoupling between an event publisher and its subscribers.&lt;/p&gt;
&lt;p&gt;So, we want to have a nice event system that satisfies the following conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Statically typed&lt;/li&gt;
&lt;li&gt;Clear usage&lt;/li&gt;
&lt;li&gt;Easy to define new events&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since C# has the &lt;code&gt;event&lt;/code&gt; data type, which allows you to define events and start utilizing the observer pattern, let&amp;rsquo;s evaluate that first:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;delegate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;EventCallback&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;event&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EventCallback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnAccountLogin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// publish&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OnAccountLogin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;OnAccountLogin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// subscribe&lt;/span&gt;
&lt;span class="n"&gt;AccountManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnAccountLogin&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AttemptToConnect&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a bit redundant. We have to define the &lt;code&gt;delegate&lt;/code&gt;, check for &lt;code&gt;null&lt;/code&gt; if we want to trigger the event, and the line isn&amp;rsquo;t very clear between who is the publisher, and who is the subscriber. Both perform a call on the event itself, after all..&lt;/p&gt;
&lt;p&gt;The developer working with me took a slightly simpler approach using the &lt;code&gt;Action&lt;/code&gt; class:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnTurnTimeUpdated&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;TurnTimeUpdated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OnTurnTimeUpdated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;OnTurnTimeUpdated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// publish &lt;/span&gt;
&lt;span class="n"&gt;UIEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TurnTimeUpdated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// subscribe&lt;/span&gt;
&lt;span class="n"&gt;UIEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onTurnTimeUpdated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;TurnTimeUpdateHandler&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It gets super annoying after defining a few events, rewriting that null check and extra method each and every single time&amp;hellip;&lt;/p&gt;
&lt;p&gt;This also has a horrible side effect .. Multiple times, the game crashed because someone was triggering the &lt;code&gt;Action&lt;/code&gt; object directly, instead of going through the method!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// instead of doing this...&lt;/span&gt;
&lt;span class="n"&gt;UIEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TurnTimeUpdated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// they did this...&lt;/span&gt;
&lt;span class="n"&gt;UIEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;onTurnTimeUpdated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code above illustrates two valid ways to trigger the event, however, the second approach crashes the game if there aren&amp;rsquo;t any handlers, since it&amp;rsquo;s missing a &lt;code&gt;null&lt;/code&gt; check. This made me seek C# for some yoga lessons and introduce some versatile construct that can solve this issue.&lt;/p&gt;
&lt;h2&gt;Enter DKEvent&lt;/h2&gt;
&lt;p&gt;I called the class &lt;code&gt;DKEvent&lt;/code&gt;, and this is how you can use it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DKEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnAuthStarted&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DKEvent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// publish&lt;/span&gt;
&lt;span class="n"&gt;UIEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnAuthStarted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// subscribe&lt;/span&gt;
&lt;span class="n"&gt;UIEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnAuthStarted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;AuthHandler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally! No &lt;code&gt;null&lt;/code&gt; checks, very clear distinction between publishing and subscribing, and best of all, it&amp;rsquo;s a single line of code to define new events! How can we achieve this beauty?&lt;/p&gt;
&lt;p&gt;Simple enough, by using generics!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DKEvent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;DKEvent&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;D0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;D0&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Trigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;D0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&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;Things to note about the code above:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You can redefine the same class name, but with different number of generic arguments, as many times as you like.&lt;/li&gt;
&lt;li&gt;We have finally encapsulated the &lt;code&gt;null&lt;/code&gt; check, and we simply define new events using the code we saw earlier.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Stored Properties&lt;/h2&gt;
&lt;p&gt;Jumping directly to the second use case, which is stored properties. Imagine you have a class that has properties which need to persisted to disk. Typically, writing such property requires lots of boilerplate code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;PersistenceManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersistenceKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultParamters&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;PersistenceManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Instance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersistenceKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&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;The above code assumes you have a nice generic persistence manager class which you can easily call to store and retrieve properties as needed. This code isn&amp;rsquo;t too bad, but we can do better.&lt;/p&gt;
&lt;p&gt;Using the same approach demonstrated earlier, we can replace the code above with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;StoredProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;StoredProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PersistenceKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;GameParameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultParamters&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code may look ugly, but it&amp;rsquo;s just a one liner. With a single line, we can define a new stored property, without the need to rewrite the calls to the persistence manager and whatnot. In order to use the new code, however, we have to use the designated accessors:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;params&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is because of the way &lt;code&gt;StoredProperty&lt;/code&gt; is implemented:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;StoredProperty&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;where&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;StoredProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;G&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;persistence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="w"&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;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The only reason I know so much about generics is because I&amp;rsquo;ve played around it a lot with Swift. In swift, you can achieve a hell lot more than what was presented here, thanks to protocol extensions and type inference.&lt;/p&gt;
&lt;p&gt;This feels like a rushed post :( .. it probably is&amp;hellip; I just really didn&amp;rsquo;t want one whole month to pass without posting anything!!&lt;/p&gt;</content><category term="posts"></category><category term="csharp"></category></entry><entry><title>Spitting It Out</title><link href="https://mazyod.com/blog/2016/08/07/spitting-it-out/" rel="alternate"></link><published>2016-08-07T18:26:02+00:00</published><updated>2016-08-07T18:26:02+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-07:/blog/2016/08/07/spitting-it-out/</id><summary type="html">&lt;p&gt;Not a very friendly title, but I really need to throw out there what&amp;rsquo;s happening these days. It&amp;rsquo;s too valuable to be lost in translation or in a long term memory archives&amp;hellip;&lt;/p&gt;
&lt;p&gt;For starters, I finally realized that toon shaders don&amp;rsquo;t cut it no more.. They are …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Not a very friendly title, but I really need to throw out there what&amp;rsquo;s happening these days. It&amp;rsquo;s too valuable to be lost in translation or in a long term memory archives&amp;hellip;&lt;/p&gt;
&lt;p&gt;For starters, I finally realized that toon shaders don&amp;rsquo;t cut it no more.. They are way too complicated for flat design! Besides, the whole idea behind toon shaders is to emphasize the edges and clean the surface of an otherwise rough texture.&lt;/p&gt;
&lt;p&gt;So, while looking around the Unity project, I deleted the folder containing the toon shaders by mistake, and decide the heck with it. Let me find a better way to do dis.&lt;/p&gt;
&lt;p&gt;Finally, I realize that the &amp;ldquo;Mobile&amp;rdquo; category in Unity shaders isn&amp;rsquo;t for low quality shaders. In fact they are high quality, just optimized for mobile by limiting certain functionality. Over there I found VertexLit shader and Unlit.&lt;/p&gt;
&lt;p&gt;Skipping VertexLit, Unlit was all I needed, really. Using the Unlit shader meant that the model texture will be draws AS IS, without any modification whatsoever by lighting, reflection or shadows in the render scene. For my flat game, this is a godsend.&lt;/p&gt;
&lt;p&gt;After applying that shader and seeing how great the game started to look, I also decided to do a quick pass over the textures that were added to the game. Changing those as well helped me achieve the absolute perfect look I was aiming for! Yatta! Well.. one nuisance is that the 3D models themselves still look a bit off, but whatever.&lt;/p&gt;
&lt;p&gt;The other thing which tempted me to write this post was the discovery of the &lt;code&gt;global&lt;/code&gt; namespace in csharp, lol. I was having issues using a global class because I had defined the same name in a local scope&amp;hellip; MonoDevelop was an absolute hero by suggesting that there is conflict with &lt;code&gt;global::ClassName&lt;/code&gt;. Nice!! So, in order to use the global name, just add &lt;code&gt;global::&lt;/code&gt;, and we are good to go..&lt;/p&gt;
&lt;p&gt;That wraps it up for now, I need to go back to work! :D&lt;/p&gt;</content><category term="devlog"></category><category term="null"></category></entry><entry><title>Anonymous Socket</title><link href="https://mazyod.com/blog/2016/08/04/anonymous-socket/" rel="alternate"></link><published>2016-08-04T16:45:04+00:00</published><updated>2016-08-04T16:45:04+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-04:/blog/2016/08/04/anonymous-socket/</id><summary type="html">&lt;p&gt;Even though I set the title as &amp;ldquo;Anonymous Socket&amp;rdquo;, I decided not to go that route after all&amp;hellip;&lt;/p&gt;
&lt;p&gt;Here is a quick brief of what&amp;rsquo;s going on inside my head:&lt;/p&gt;
&lt;p&gt;I need anonymous clients to connect to the backend and generate a temporary guest account to use in case …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Even though I set the title as &amp;ldquo;Anonymous Socket&amp;rdquo;, I decided not to go that route after all&amp;hellip;&lt;/p&gt;
&lt;p&gt;Here is a quick brief of what&amp;rsquo;s going on inside my head:&lt;/p&gt;
&lt;p&gt;I need anonymous clients to connect to the backend and generate a temporary guest account to use in case the user doesn&amp;rsquo;t want to create an account. In order to create the guest account, I have implemented a simple REST API.&lt;/p&gt;
&lt;p&gt;After looking at the implementation on the client side, I realized that using Phoenix channels is way simpler and easier than performing API calls, so I was thinking of creating a new socket endpoint for anonymous clients. A client would connect anonymously, and be given a grace period of 5 minutes or so to perform the actions it needs, such as registration or login.&lt;/p&gt;
&lt;p&gt;The second idea sounded great, easy to implement, and in alignment with the rest of the backend .. SHIKASHI!&lt;/p&gt;
&lt;p&gt;It would mean I&amp;rsquo;d have to manage anonymous states and sockets, which can quickly become vague and cumbersome. When using REST APIs, the request/response cycle is all you have to worry about. Once the response is sent back to the client, it&amp;rsquo;s over.&lt;/p&gt;
&lt;p&gt;With that in mind, I figured in the future I&amp;rsquo;ll have a separate &amp;ldquo;authoritative&amp;rdquo; server that would deal with these anonymous pricks and issue secure tokens for them to access the game servers. With that in mind, if I use a REST API, it would be easier to use Heroku or some other service and language to distribute the risk/load across many servers&amp;hellip; I&amp;rsquo;m probably over-thinking this at this point xD&lt;/p&gt;
&lt;p&gt;Honestly, the real reason to leave the anonymous socket behind for now is time. I keep thinking about how the anonymous socket implementation is gonna be, when I already have a working implementation of the REST API client and server. So, for the sake of time, let&amp;rsquo;s stick with the REST API.&lt;/p&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;With that being said, I really need to move on to implementing the functionality required to register/login the user. The API is implemented, but still not hooked up to the UI yet&amp;hellip; Should be simple enough to do that.&lt;/p&gt;
&lt;p&gt;Once that&amp;rsquo;s done, I should focus on logout, figure out how that should work, while making sure the user has the ability to recover their account&amp;hellip; Finally, I really need to implement social login, for simplicity sake. Even Pokemon Go uses Google sign up, which means it&amp;rsquo;s the way to go.&lt;/p&gt;
&lt;p&gt;&amp;hellip;&lt;/p&gt;
&lt;p&gt;You know, for the logout stuff, I really have no choice but to add an email field when the user chooses to upgrade their guest account. The user would already be invested, anyway, and it will be for their sake so they don&amp;rsquo;t lose their account. As for social login, the beauty is that we don&amp;rsquo;t have to worry about them losing access there.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>More Errors</title><link href="https://mazyod.com/blog/2016/08/04/more-errors/" rel="alternate"></link><published>2016-08-04T14:08:23+00:00</published><updated>2016-08-04T14:08:23+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-04:/blog/2016/08/04/more-errors/</id><summary type="html">&lt;p&gt;Even more errors, and more edge cases to solve &amp;hellip; If you are developing a game, really there is never a dull moment around here .. Every single detail is a challenge that requires careful thought and planning. The idea is that once you start executing, everything should just fall into place …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Even more errors, and more edge cases to solve &amp;hellip; If you are developing a game, really there is never a dull moment around here .. Every single detail is a challenge that requires careful thought and planning. The idea is that once you start executing, everything should just fall into place.&lt;/p&gt;
&lt;p&gt;So, back to the issue at hand .. After handling the simple error dialogs part and food, now I reached the game scene, and need to handle the errors there. As highlighted previously, the game view syncs the game scene graphics through an event queue .. So, I could just create a new event for channel errors and call it a day .. But, there are many types of errors that could occur in a game.&lt;/p&gt;
&lt;p&gt;First, there is the join error. So, the player somehow reached the game scene, but due to some circumstances, the game is no longer available, so that results in a join error. I think this is simple since I can just enqueue a join error event to the events queue, and it will be handled gracefully. This works well because I actually also have a &amp;ldquo;game ready&amp;rdquo; event in place which is only sent to the graphics part if the game has initialized successfully.&lt;/p&gt;
&lt;p&gt;Then, there are two other errors related to rematch. Since rematch is a paid action, therefor the request may be rejected due to insufficient funds. Another issue may happen when a rematch is requested, but it goes away before that packet reaches the server.&lt;/p&gt;
&lt;p&gt;I think that in either case I can just handle the error as a &amp;ldquo;Rematch Unavailable&amp;rdquo; event, which is already in place. That event will disable the rematch button, and show a label &amp;ldquo;rematch unavailable&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Hopefully, this will resolve all the channel error handling, for now!&lt;/p&gt;
&lt;p&gt;The only missing piece in the game after that is implementing a proper account flow, where users can create accounts, login with existing accounts, logout, and hopefully be able to recover accounts .. I can&amp;rsquo;t believe I&amp;rsquo;m saying this .. But once that&amp;rsquo;s implemented, it&amp;rsquo;s time for BETA TESTING!!&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>Errors Localization</title><link href="https://mazyod.com/blog/2016/08/04/errors-localization/" rel="alternate"></link><published>2016-08-04T12:01:48+00:00</published><updated>2016-08-04T12:01:48+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-04:/blog/2016/08/04/errors-localization/</id><summary type="html">&lt;p&gt;Forgot that on a similar note to the previous post, I was wondering how I should deal with error message localization. I can deal with the localization on the frontend or the backend. If I choose either, there are also multiple ways to approach either one&amp;hellip; Then, there is the …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Forgot that on a similar note to the previous post, I was wondering how I should deal with error message localization. I can deal with the localization on the frontend or the backend. If I choose either, there are also multiple ways to approach either one&amp;hellip; Then, there is the hybrid approach, where the backend sends all localized strings, and the client picks the right one&amp;hellip;&lt;/p&gt;
&lt;p&gt;Ideally, I would probably just tag the locale when opening the socket, assign that to the socket assigns map, and use that throughout the backend to return the appropriate localized string&amp;hellip; Actually, I really should do just that.&lt;/p&gt;
&lt;p&gt;In elixir, people seem to be using &lt;code&gt;gettext&lt;/code&gt; to localize stuff, but I haven&amp;rsquo;t tested it out yet, hopefully it&amp;rsquo;ll be simple to use, and would solve this issue for me.&lt;/p&gt;
&lt;p&gt;Well, I guess that&amp;rsquo;s it then! Just attach the locale to the socket when joining.&lt;/p&gt;</content><category term="devlog"></category><category term="null"></category></entry><entry><title>errors</title><link href="https://mazyod.com/blog/2016/08/04/errors/" rel="alternate"></link><published>2016-08-04T10:42:36+00:00</published><updated>2016-08-04T10:42:36+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-04:/blog/2016/08/04/errors/</id><summary type="html">&lt;p&gt;Hmm.. here I am again just typing stuff instead of working on my game .. This is the penalty of inexperience and lack of another brain to bounce ideas off of..&lt;/p&gt;
&lt;p&gt;Well, the issue I am facing now is dealing with backend errors on the client side. The backend gracefully handle …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Hmm.. here I am again just typing stuff instead of working on my game .. This is the penalty of inexperience and lack of another brain to bounce ideas off of..&lt;/p&gt;
&lt;p&gt;Well, the issue I am facing now is dealing with backend errors on the client side. The backend gracefully handle extreme cases, such as insufficient coins and state unavailability by returning errors to the client &amp;hellip;&lt;/p&gt;
&lt;p&gt;Now, they are extreme cases because normally, the client app will check if the player does indeed have enough coins or not and warn them without really bothering the backend. It is only if the client data somehow gets out of sync, or if a player thinks themself smart enough to hack the game is when we reach this case.&lt;/p&gt;
&lt;p&gt;With that being said, I realize that I don&amp;rsquo;t really need dokubetsu handling for these cases, especially not for version 1.0 .. I should just roll with simple dialogs and what now, and move on.&lt;/p&gt;
&lt;p&gt;The only issue is that I should always handle joining errors, no matter what the reason is, because otherwise I would have a reference to a dead channel and the game state would think it is active. That won&amp;rsquo;t do at all.&lt;/p&gt;
&lt;p&gt;So, first I should rename &lt;code&gt;OnError&lt;/code&gt; function to &lt;code&gt;OnJoinError&lt;/code&gt;, since that&amp;rsquo;s more representative of what&amp;rsquo;s going on. Then, I can handle those errors by resetting the channel somehow&amp;hellip; Then, we can have specific error delegate methods per channel, per reply use case. You see, these errors that I am handling here aren&amp;rsquo;t random. The are specifically created and sent by the backend. So, I&amp;rsquo;ll just create delegate methods for each, and handle them as appropriate.&lt;/p&gt;
&lt;p&gt;Whenever things click so well, my mind just wanders off in the distance on how I can leverage this perfection in different applications&amp;hellip; I then need to pull myself back to reality and focus on finishing this crap.&lt;/p&gt;
&lt;p&gt;Well, let&amp;rsquo;s do this and hope it works out!&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>rants</title><link href="https://mazyod.com/blog/2016/08/02/rants/" rel="alternate"></link><published>2016-08-02T15:14:01+00:00</published><updated>2016-08-02T15:14:01+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-08-02:/blog/2016/08/02/rants/</id><summary type="html">&lt;p&gt;Just needed a quick way to track some tasks, so here it goes&amp;hellip;&lt;/p&gt;
&lt;p&gt;Found a bunch of crap surrounding the dialog implementation. Most of it was easy to cleanup, however, the animation code I just can&amp;rsquo;t find it&amp;hellip; Looking at how the dialog isn&amp;rsquo;t deactivated nor cleaned up …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Just needed a quick way to track some tasks, so here it goes&amp;hellip;&lt;/p&gt;
&lt;p&gt;Found a bunch of crap surrounding the dialog implementation. Most of it was easy to cleanup, however, the animation code I just can&amp;rsquo;t find it&amp;hellip; Looking at how the dialog isn&amp;rsquo;t deactivated nor cleaned up after being hidden also made me decide to just not cache panels....&lt;/p&gt;
&lt;p&gt;Like, I&amp;rsquo;ve specifically had this talk with the developer, telling him:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are two hard problems in Computer Science, the first being cache invalidation.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yet, he insisted &amp;ldquo;it&amp;rsquo;s easy to cache&amp;rdquo;. Sigh. Yeah, you just store the crap in a variable and call it done&amp;hellip; Completely ignoring the invalidation part, amazing.&lt;/p&gt;
&lt;p&gt;So, let&amp;rsquo;s clean that up&amp;hellip; OK, cache nuked&amp;hellip; Running&amp;hellip; Works as expected in most of the pleaganels, but the dialog stuff is interesting, since the dialog simply just stays there after the animation, and a new one is instantiated if we click again, leaking the old one&amp;hellip; So, need to resolve the dialog flow.&lt;/p&gt;
&lt;p&gt;Hmm&amp;hellip; cleaned up a few scripts around panel controller, and forgot what the hell I was doing&amp;hellip; Oh, dialogs&amp;hellip; How are they even managed?&lt;/p&gt;
&lt;p&gt;Well, it was pretty neat, actually. There was a script that automatically searched for any tween component in panel you push, and triggers it. Once I searched the prefab for that tween component, it was simple to alter the flow and fix stuff&amp;hellip; Still need to figure out why the dialogs aren&amp;rsquo;t being destroyed&amp;hellip;&lt;/p&gt;
&lt;p&gt;I finally figured out why it was so hard to read the flow of the code.. It is basically because different things were doing the same thing&amp;hellip; I mean, imagine you have a navigation stack. You push stuff onto the stack, then pop them out &amp;hellip; When you push things, the existing thing is gonna be hidden. Also, when you pop from the stack, and popped thing is gonna be hidden.. Now, just because they are both gonna be hidden, doesn&amp;rsquo;t mean they should lead to the same function!! The pop flow should be completely separate from the push flow.&lt;/p&gt;
&lt;p&gt;Well, one more stupid bug, pushing more than one panel seems to stop the push animation from working &lt;code&gt;&amp;gt;___&amp;lt;&lt;/code&gt; &amp;hellip;&lt;/p&gt;
&lt;p&gt;lol, indeed it was stupid&amp;hellip; ROFL, this is just too stupid. So, while I was fixing the panel controller code, which deals with the whole navigation crap, I saw that a variable was defined like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Panel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_panelStack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I was like, no way! This is called a stack, it should be a stack!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Stack&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Panel&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_panelStack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Better&amp;hellip; So, I go through the code and change &lt;code&gt;Remove&lt;/code&gt; to &lt;code&gt;Pop&lt;/code&gt; .. and that&amp;rsquo;s it. I leave everything else the same, including calls to the &lt;code&gt;Last&lt;/code&gt; function. By definition, a stack puts new elements at the beginning, and I was accessing &lt;code&gt;Last&lt;/code&gt; &amp;hellip; Stupid. So, just changed those to &lt;code&gt;Peek&lt;/code&gt;, and call it a day.&lt;/p&gt;</content><category term="devlog"></category><category term="null"></category></entry><entry><title>Come Again?</title><link href="https://mazyod.com/blog/2016/07/30/come-again/" rel="alternate"></link><published>2016-07-30T22:04:18+00:00</published><updated>2016-07-30T22:04:18+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-30:/blog/2016/07/30/come-again/</id><summary type="html">&lt;p&gt;So, after spending all that time perfecting the relationship between the game logic, graphics, and view, the game started coming together. Implementing new crap is much simpler, since everything is where it belongs, and it doesn&amp;rsquo;t take time to think about where to implement it.&lt;/p&gt;
&lt;p&gt;With that, my trello …&lt;/p&gt;</summary><content type="html">&lt;p&gt;So, after spending all that time perfecting the relationship between the game logic, graphics, and view, the game started coming together. Implementing new crap is much simpler, since everything is where it belongs, and it doesn&amp;rsquo;t take time to think about where to implement it.&lt;/p&gt;
&lt;p&gt;With that, my trello board quickly started draining down cards, thankfully, but it&amp;rsquo;s way too early to celebrate.&lt;/p&gt;
&lt;p&gt;Speaking of celebration, I was psyched to see the game performance go through the roof after simply turning off a clipping feature in NGUI. It had something to do with Physx processing, hogging tons of resource.. So, I wanted to check if the performance gain was real, and wanted to build the game on iOS.&lt;/p&gt;
&lt;p&gt;As I was making changes and pushing to github, the iOS build on UCB kept failing&amp;hellip; Weird.. It usually fails for no reason from time to time, but now it failed like 3 times in a row! Something was amiss.&lt;/p&gt;
&lt;p&gt;Well, the biggest change I made which impacted platform specific stuff was upgrading the native dama logic plugin. I&amp;rsquo;ve made changes in the library to remove dynamic memory allocation from certain parts, in order to simplify memory management a bit &amp;hellip; which was nice, but it&amp;rsquo;s a chore to build the library and update the server, bots, and unity with the new version.&lt;/p&gt;
&lt;p&gt;So, after spending an hour or two updating and running the new library on the servers, after updating Pyport obviously, which is the python shim wrapping the C library, I updated unity simply by replacing the old libraries with the new ones. At that point, I hastily tested the Mac build, which worked fine, so life went on.&lt;/p&gt;
&lt;p&gt;Now, after seeing the iOS build failures pile up, I looked deeper into the logs, and yup&amp;hellip; the dreaded iOS native lib was causing issues because of some undefined symbols. The annoying this was the Unity itself generated C++ code through IL2Cpp that was named exactly the same name as my native code, except it had a number suffix at the end, like &lt;code&gt;xyz_m12839213&lt;/code&gt;. This made the linker go, &amp;ldquo;Did you mean xyz_m12839213?&amp;rdquo;. I&amp;rsquo;m like, no! the suffix shouldn&amp;rsquo;t be there!&lt;/p&gt;
&lt;p&gt;So I dig through my blog, go over git changes like 5 times to see what changed?? I did upgrade Unity to 5.4.0F2, but seriously? Even cloud build was failing, so it should be something else&amp;hellip;&lt;/p&gt;
&lt;p&gt;Finally, I use the best tool for inspecting libraries, &lt;code&gt;nm&lt;/code&gt;. Using it revealed that indeed all the &amp;ldquo;glue code&amp;rdquo; generated by SWIG, to glue the C code with CSharp was missing! Going back to the Xcode project that built the native library, it seems that yeah &amp;hellip; I was an idiot at some point and excluded that file from the build &lt;code&gt;&amp;gt;_&amp;lt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;So, finally, I mark that file as part of the built library, build the library, and off to Unity it goes &amp;hellip; The issue now is, I&amp;rsquo;ve built too many times within a short period of time on UCB, so it will be a while till my build will be executed &amp;hellip; Too lazy to build it locally, so just distracting myself with this blog entry and probably going out for food&amp;hellip; Hopefully, it will be ready after that.&lt;/p&gt;
&lt;p&gt;Once it&amp;rsquo;s really, it would be time to download it on an iPad and hope for that sweet, sweet 60 FPS glamor &lt;code&gt;*_*&lt;/code&gt;.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>The Fuck Up</title><link href="https://mazyod.com/blog/2016/07/26/the-fuck-up/" rel="alternate"></link><published>2016-07-26T19:31:34+00:00</published><updated>2016-07-26T19:31:34+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-26:/blog/2016/07/26/the-fuck-up/</id><summary type="html">&lt;p&gt;I derailed, and I derailed hard&amp;hellip;&lt;/p&gt;
&lt;p&gt;I was simply focused on trying to implement animation ended hooks, so whenever an animation ends, the main game loop is informed, and the next task is processed&amp;hellip;&lt;/p&gt;
&lt;p&gt;Somehow, during that implementation, I found a nasty part in the project, but it was working …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I derailed, and I derailed hard&amp;hellip;&lt;/p&gt;
&lt;p&gt;I was simply focused on trying to implement animation ended hooks, so whenever an animation ends, the main game loop is informed, and the next task is processed&amp;hellip;&lt;/p&gt;
&lt;p&gt;Somehow, during that implementation, I found a nasty part in the project, but it was working well for the most part. For some reason, I decided to rewrite it&amp;hellip; That was such a horrible idea.&lt;/p&gt;
&lt;p&gt;No matter what the end result is, spending 4 - 5 hours perfecting minor stuff isn&amp;rsquo;t what I should be concerned about now, and yet! In any case, I realized now that reverting might be even more painful, so I gotta get this through.&lt;/p&gt;
&lt;p&gt;The thing I really need to think through now is how should I structure the UI code moving forward? My options are either to keep things decoupled and work through the global event system, or better yet, go back to having hard references to each part of the UI.&lt;/p&gt;
&lt;p&gt;Even though having references couples things, but allows for much higher control and clarity, which is something I really need for this game. Hiring developers not aligned with me on this part was a huge mistake&amp;hellip;&lt;/p&gt;
&lt;p&gt;OK, let&amp;rsquo;s just get this &amp;ldquo;hanging&amp;rdquo; task over with, I guess&amp;hellip;&lt;/p&gt;</content><category term="devlog"></category><category term="null"></category></entry><entry><title>Event Stream</title><link href="https://mazyod.com/blog/2016/07/23/event-stream/" rel="alternate"></link><published>2016-07-23T18:06:19+00:00</published><updated>2016-07-23T18:06:19+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-23:/blog/2016/07/23/event-stream/</id><summary type="html">&lt;p&gt;After much struggling, procrastinating, and LoLing, I have finally set my mind to it. Previously, I have explained how I should be moving the game state within the game logic, but once I started looking at the code some more, something stood out.&lt;/p&gt;
&lt;p&gt;The graphics part was tightly coupled with …&lt;/p&gt;</summary><content type="html">&lt;p&gt;After much struggling, procrastinating, and LoLing, I have finally set my mind to it. Previously, I have explained how I should be moving the game state within the game logic, but once I started looking at the code some more, something stood out.&lt;/p&gt;
&lt;p&gt;The graphics part was tightly coupled with the game state. I was basically reading the game state each turn, and updating the graphics accordingly. This is great for extremely simple graphics, but it&amp;rsquo;s impossible to have proper animations and sequential graphic events this way &amp;hellip;&lt;/p&gt;
&lt;p&gt;To give you an example, imagine how we can implement a &amp;ldquo;game turn indicator&amp;rdquo; widget. The widget is a simple arrow that points at either the white or black team, based on the turn.&lt;/p&gt;
&lt;p&gt;Currently, I am reading the game state each turn and updating the turn! This is nice because I am not assuming the turn is simply switching colors each turn. So, if the state is reloaded for any reason, everything just works out of the box&amp;hellip;&lt;/p&gt;
&lt;p&gt;However, this restricts us in terms of what we can do for animations. You see, since we can&amp;rsquo;t assume the turn switch, we can&amp;rsquo;t implement a simple turn change animation, unless we hold a diff state in the GUI! Something like, if previous turn doesn&amp;rsquo;t equal next turn, then switch&amp;hellip; This is ugly, and shouldn&amp;rsquo;t be handled by the graphics part.&lt;/p&gt;
&lt;p&gt;Another problem I was facing with this load-from-scratch-each-time approach is overlapping events. If during an online game a move comes in, and we want to apply that, obviously an animation will be started. What if during that animation, a game ended event comes in? If we keep inspecting the whole game state each time, it would be pretty hard to accommodate all these cases&amp;hellip;&lt;/p&gt;
&lt;p&gt;This leaves me with the hopefully most simple and elegant solution .. An event queue. Every single change on the graphics side has to be driven by a game logic event, be it a turn change, play move, or game ended. The graphics part simply &amp;ldquo;blocks&amp;rdquo; on that queue, and process it one at a time.&lt;/p&gt;
&lt;p&gt;This tasks seems intimidating, and I&amp;rsquo;m trying to summon every last bit of willpower I have left for this game to pull it through &amp;hellip; I keep running into these issues, which is the most frustrating part. It&amp;rsquo;s definitely my fault for spending unreasonable time on polish before figuring these details out, but all I can do now is learn the lesson and move on.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>State, Logic, and Graphics</title><link href="https://mazyod.com/blog/2016/07/23/state-logic-and-graphics/" rel="alternate"></link><published>2016-07-23T09:47:25+00:00</published><updated>2016-07-23T09:47:25+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-23:/blog/2016/07/23/state-logic-and-graphics/</id><summary type="html">&lt;p&gt;I am struggling to find the zen between three entities in my game:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Logic&lt;/li&gt;
&lt;li&gt;Graphics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;the game state is an immutable object that simply represents the state of the game. If you want to change the game state, a new copy is created. This makes game state super simple …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I am struggling to find the zen between three entities in my game:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;State&lt;/li&gt;
&lt;li&gt;Logic&lt;/li&gt;
&lt;li&gt;Graphics&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;the game state is an immutable object that simply represents the state of the game. If you want to change the game state, a new copy is created. This makes game state super simple and easy to pass around with having to worry about it. As a bonus, implementing undo is literally as simple as having a stack of these game state objects.&lt;/p&gt;
&lt;p&gt;Then we have the game logic. This is where the current game state is saved, and where the update loop happens, telling us if the game ended, or other similar events. The tricky part about this entity is that it could either be local or remote. When playing online, the logic actually completely runs on the server.&lt;/p&gt;
&lt;p&gt;Finally, we have the graphics, which is the representation of the game logic and game state to the user. It needs the game state information in order to &amp;ldquo;know&amp;rdquo; what are the available moves, and that&amp;rsquo;s about it.&lt;/p&gt;
&lt;p&gt;Seems simple, except when you try to organize these entities around working with singleplayer, local multiplayer, and online multiplayer. The proper abstraction needs to be in place in order for things to work properly.&lt;/p&gt;
&lt;p&gt;The most challenging aspect of singleplayer is handling the undo action. Sure it&amp;rsquo;s as simple as a stack of &lt;code&gt;GameState&lt;/code&gt; objects, but finding the right place in these entities to put it and update the game is tricky. Then, we have the fact that the game logic runs on the server in online games, and the game can end at &lt;strong&gt;any given time&lt;/strong&gt;, if a player surrenders or disconnects, for example. We somehow need to signal that the game has ended at that point.&lt;/p&gt;
&lt;p&gt;With all these pieces in mind &amp;hellip; There is only one answer I can think of. Make the logic hold the current game state, and that way, we can do the following:&lt;/p&gt;
&lt;p&gt;For the remote game logic, we simply keep the game state in sync with the server, publishing new events to the graphics part. For the local game logic, we immediately apply changes to the game state, and publish the change events back to the graphics &amp;hellip; This should do it, I hope.&lt;/p&gt;
&lt;p&gt;Sad part about this is, I was struggling with designing this and spent countless hours refactoring stuff back and forth because of an extremely old design mistake made in the Dama C library. In the library, I had made the GameState stateful, which was a premature optimization back in 2012!!! Haunted me to this day .. So, finally removed that optimization, cleaned stuff up, and now everything is yet simpler and easier to reason with.&lt;/p&gt;
&lt;p&gt;All these changes I&amp;rsquo;ve been making for a whole week, btw, are for the simple reason that I need to implement &amp;ldquo;forced moves&amp;rdquo; from the server. You see, when a player fails to make a move within the alloted time, the server forced a move on them. This is very hard to accommodate without proper code design, because until now, I always assumed that moves are coming from the actual players! So, if it&amp;rsquo;s the local player, it has to come from the graphics interaction part of the game &amp;hellip; Not the case anymore.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>Smarter Game Results</title><link href="https://mazyod.com/blog/2016/07/22/smarter-game-results/" rel="alternate"></link><published>2016-07-22T13:10:21+00:00</published><updated>2016-07-22T13:10:21+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-22:/blog/2016/07/22/smarter-game-results/</id><summary type="html">&lt;p&gt;Damn, that&amp;rsquo;s why I was stuck on this all along!!&lt;/p&gt;
&lt;p&gt;Remember the &lt;code&gt;GameResult&lt;/code&gt; problem where I was thinking of how to represent who won? Well, the reason it was a bit more complicated than it seems is because I have &amp;ldquo;smart game results&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t generate a single …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Damn, that&amp;rsquo;s why I was stuck on this all along!!&lt;/p&gt;
&lt;p&gt;Remember the &lt;code&gt;GameResult&lt;/code&gt; problem where I was thinking of how to represent who won? Well, the reason it was a bit more complicated than it seems is because I have &amp;ldquo;smart game results&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t generate a single &lt;code&gt;GameResult&lt;/code&gt; and send it to all players, since there is player specific information, namely the rewards and rating delta. Instead, I generate a unique &lt;code&gt;GameResult&lt;/code&gt; per player.&lt;/p&gt;
&lt;p&gt;With that being said, it would be ideal to make use of this characteristic and just embed a simple enum in the &lt;code&gt;GameResult&lt;/code&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;won&lt;/li&gt;
&lt;li&gt;lost&lt;/li&gt;
&lt;li&gt;draw&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&amp;rsquo;s it. I tell each player whether they won, lost, or if it was a draw&amp;hellip; Will play nicely with Elixir, and make my life easier on the frontend side as well.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>Better Late Than Never</title><link href="https://mazyod.com/blog/2016/07/22/better-late-than-never/" rel="alternate"></link><published>2016-07-22T13:03:01+00:00</published><updated>2016-07-22T13:03:01+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-22:/blog/2016/07/22/better-late-than-never/</id><summary type="html">&lt;p&gt;Wow, I really should have started doing this since forever &amp;hellip; But you you what they always say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Better late than never&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I mean, really, so many problems could have been preserved .. I&amp;rsquo;ve written a lot of them on white boards, idea paint walls, notebooks, notepads, and even voice notes …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Wow, I really should have started doing this since forever &amp;hellip; But you you what they always say:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Better late than never&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I mean, really, so many problems could have been preserved .. I&amp;rsquo;ve written a lot of them on white boards, idea paint walls, notebooks, notepads, and even voice notes, lol.&lt;/p&gt;
&lt;p&gt;Well, time to get that task from the previous post out of the way, then it&amp;rsquo;s time for munching lunch.&lt;/p&gt;</content><category term="devlog"></category><category term="rant"></category></entry><entry><title>Who Won?</title><link href="https://mazyod.com/blog/2016/07/22/who-won/" rel="alternate"></link><published>2016-07-22T12:41:26+00:00</published><updated>2016-07-22T12:41:26+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-22:/blog/2016/07/22/who-won/</id><summary type="html">&lt;p&gt;In Dama, a game ends under the following conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A player disconnects&lt;/li&gt;
&lt;li&gt;A player surrenders&lt;/li&gt;
&lt;li&gt;The players agree on a draw&lt;/li&gt;
&lt;li&gt;The game reaches a draw state&lt;/li&gt;
&lt;li&gt;The game reaches an ended state&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So many different ways to end the game, and thankfully it was super simple to streamline all …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In Dama, a game ends under the following conditions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A player disconnects&lt;/li&gt;
&lt;li&gt;A player surrenders&lt;/li&gt;
&lt;li&gt;The players agree on a draw&lt;/li&gt;
&lt;li&gt;The game reaches a draw state&lt;/li&gt;
&lt;li&gt;The game reaches an ended state&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So many different ways to end the game, and thankfully it was super simple to streamline all this in Elixir. It&amp;rsquo;s actually quite neat, and would make for a nice post one day&amp;hellip;&lt;/p&gt;
&lt;p&gt;In any case, when the game ends, the backend sends a &lt;code&gt;game_ended&lt;/code&gt; message to the frontend, with the &lt;code&gt;GameResult&lt;/code&gt;. The game result contains the rewards the players get, if any, as well as the new rating of the players, if those changed.&lt;/p&gt;
&lt;p&gt;For now, I need to figure out how should the frontend handle this? Since the old days, the frontend simply checked the game state to see if it&amp;rsquo;s still running, but that obviously doesn&amp;rsquo;t cover the first three termination conditions.&lt;/p&gt;
&lt;p&gt;So, the best way to go about this is to embed the &amp;ldquo;winning&amp;rdquo; information in the &lt;code&gt;GameResult&lt;/code&gt; payload. It would need to represent the following information:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;winner -&amp;gt; player x&lt;/li&gt;
&lt;li&gt;draw&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;in Elixir, I usually represent this using atoms and tuples as follows:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:winner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:white_player&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:draw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That doesn&amp;rsquo;t translate well to CSharp for the frontend .. I guess my options are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;String: &amp;ldquo;winner:player&amp;rdquo;, &amp;ldquo;draw&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Enum: winner_white, winner_black, draw&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can&amp;rsquo;t think of any other viable options, really &amp;hellip; The enum approach sounds nice, but would be painful to debug if the backend and frontend fall out of sync .. So, strings is the way to go.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>A New Beginning</title><link href="https://mazyod.com/blog/2016/07/22/a-new-beginning/" rel="alternate"></link><published>2016-07-22T11:53:31+00:00</published><updated>2016-07-22T11:53:31+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-22:/blog/2016/07/22/a-new-beginning/</id><summary type="html">&lt;p&gt;to further lower the barrier of writing to my blog, I decided to start this devlog thingie. I can just do brain dumps here without even worrying about the structure, title, content, or anything like that&amp;hellip;&lt;/p&gt;
&lt;p&gt;Well, I actually started this because I am too lazy to create a live …&lt;/p&gt;</summary><content type="html">&lt;p&gt;to further lower the barrier of writing to my blog, I decided to start this devlog thingie. I can just do brain dumps here without even worrying about the structure, title, content, or anything like that&amp;hellip;&lt;/p&gt;
&lt;p&gt;Well, I actually started this because I am too lazy to create a live programming video feed. I kinda needed to make my development experience feel more interesting than just me typing stuff into a computer &amp;hellip; So, &amp;hellip; This is really unfocused.&lt;/p&gt;
&lt;p&gt;In order to make my development experience more interesting, I decided to start this devlog. That&amp;rsquo;s sums it up.&lt;/p&gt;</content><category term="devlog"></category><category term="dama"></category></entry><entry><title>Speed Tests</title><link href="https://mazyod.com/blog/2016/07/11/speed-tests/" rel="alternate"></link><published>2016-07-11T08:29:57+00:00</published><updated>2016-07-11T08:29:57+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-11:/blog/2016/07/11/speed-tests/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Finally, I&amp;rsquo;m back in the game (literally?), and working on the Elixir side of things for a change.&lt;/p&gt;
&lt;p&gt;So, my Elixir backend is heavily tested using unit and integration test. For now, a total of 83 unit tests assert their way through my code, all way from checking …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Finally, I&amp;rsquo;m back in the game (literally?), and working on the Elixir side of things for a change.&lt;/p&gt;
&lt;p&gt;So, my Elixir backend is heavily tested using unit and integration test. For now, a total of 83 unit tests assert their way through my code, all way from checking the password hashing result, to making sure I don&amp;rsquo;t have any typos.&lt;/p&gt;
&lt;p&gt;&lt;img alt="elixir tests" src="/images/elixir-tests.png"&gt;&lt;/p&gt;
&lt;p&gt;Life wasn&amp;rsquo;t this good just yesterday. My tests were taking 7.2 seconds to run, which for Ruby people is a dream, but for Elixir folks, we can do better.&lt;/p&gt;
&lt;p&gt;So, I want to quickly explore the idea of tracking down the slow down and how I managed to resolve it.&lt;/p&gt;
&lt;h2&gt;Crypt Lord&lt;/h2&gt;
&lt;p&gt;So, in my case, it really wasn&amp;rsquo;t too hard to track down the slowdown. After integrating the authentication features, which uses &lt;code&gt;Comeonin.Bcrypt&lt;/code&gt;, I noticed that a simple test is taking +300 ms to finish, sometimes +800 ms. Wat?! Why so slow?&lt;/p&gt;
&lt;p&gt;Turns out the Crypt lord is just too heavy .. Any Warcraft fans out there?&lt;/p&gt;
&lt;p&gt;&lt;img alt="crypt lord" src="/images/Cryptlord.jpg"&gt;&lt;/p&gt;
&lt;p&gt;You see, Bcrypt is slow, and that is by design. If your password database gets compromised for any reason, the hacker will have to use the purposely designed, slow algorithm to apply a rainbow table attack on the data, which would take forever. For example, just to crack a single password, it would probably take a single CPU core an excess of 5 years total.&lt;/p&gt;
&lt;p&gt;Well, that sounds great! I mean, even though it&amp;rsquo;s slow, it is secure&amp;hellip; However, while unit testing, we really don&amp;rsquo;t need this functionality at all. In fact, unit testing is by definition testing your code in small, isolated units. We can leave the actual Bcrypt testing for integration tests.&lt;/p&gt;
&lt;p&gt;So, how should we go about this?&lt;/p&gt;
&lt;h3&gt;Mockery&lt;/h3&gt;
&lt;p&gt;One could easily utilize the great &lt;a href="https://github.com/jjh42/mock"&gt;mock library&lt;/a&gt; to mock the Bcrypt module, and we are done! Unfortunately, mocking in this specific case has tons of drawbacks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You can no longer run your tests asynchronously&lt;/li&gt;
&lt;li&gt;You must repeat the mock setup anywhere your test invokes &lt;code&gt;Comeonin.Bcrypt&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is Elixir, obviously we can do better.&lt;/p&gt;
&lt;h3&gt;DI&lt;/h3&gt;
&lt;p&gt;I am not really sure if this counts as Dependency Injection, but it sure smells like it. What we basically do is head over to our configuration files and setup the modules which provide us with certain services. Based on the run configuration, we provide a different module!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# this is in config.exs&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:myapp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:modules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Comeonin.Bcrypt&lt;/span&gt;

&lt;span class="c1"&gt;# this is in test.exs&lt;/span&gt;
&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:myapp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:modules&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.BcryptStub&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, head over to your main app module, and do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Application&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;### services&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="na"&gt;@config&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:myapp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:modules&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;bcrypt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="na"&gt;@config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:bcrypt&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That&amp;rsquo;s about it. Now, instead of referencing &lt;code&gt;Comeonin.Bcrypt&lt;/code&gt; in your code everywhere, you use &lt;code&gt;MyApp.bcrypt&lt;/code&gt; instead. If your tests are running, the function will return the stub Bcrypt module which you have already setup to be speedy. While running in dev or prod configuration, the real Bcrypt module will take the wheel.&lt;/p&gt;
&lt;p&gt;For the sake of completeness, this is how I setup the &lt;code&gt;MyApp.BcryptStub&lt;/code&gt; module:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.BcryptStub&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;hashpwsalt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bcrypt-hash:&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;checkpw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;bcrypt-hash:&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pass&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;checkpw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="no"&gt;false&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, I simply replicate the functions in &lt;code&gt;Comeonin.Bcrypt&lt;/code&gt; that I am using, and replace them with a predictable &amp;ldquo;hashing&amp;rdquo; algorithm which runs in the microsecond time order.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Elixir continues to kick ass, whether it was parallelism, functionality, or just pure productivity tools. With this simple trick above, the tests now run in ~1.2 seconds. incidentally, I&amp;rsquo;ve disabled async testing because I access the DB everywhere, but once I upgrade to Phoenix 1.2.0 and turn on async testing as well, tests might as well run within 800 ms or less.&lt;/p&gt;</content><category term="posts"></category><category term="elixir"></category></entry><entry><title>Animator Trigger</title><link href="https://mazyod.com/blog/2016/07/05/animator-trigger/" rel="alternate"></link><published>2016-07-05T22:14:01+00:00</published><updated>2016-07-05T22:14:01+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-05:/blog/2016/07/05/animator-trigger/</id><summary type="html">&lt;p&gt;Less programming these days, and more animation design. I&amp;rsquo;ve been using Unity&amp;rsquo;s animation system to bring the game to life, and it&amp;rsquo;s a pretty solid system, I have to say.&lt;/p&gt;
&lt;p&gt;&lt;img alt="states-image" src="/images/states.png"&gt;&lt;/p&gt;
&lt;p&gt;As with all things Unity, it has gotchas, so this post will cover some of them.&lt;/p&gt;
&lt;h3&gt;Triggers …&lt;/h3&gt;</summary><content type="html">&lt;p&gt;Less programming these days, and more animation design. I&amp;rsquo;ve been using Unity&amp;rsquo;s animation system to bring the game to life, and it&amp;rsquo;s a pretty solid system, I have to say.&lt;/p&gt;
&lt;p&gt;&lt;img alt="states-image" src="/images/states.png"&gt;&lt;/p&gt;
&lt;p&gt;As with all things Unity, it has gotchas, so this post will cover some of them.&lt;/p&gt;
&lt;h3&gt;Triggers&lt;/h3&gt;
&lt;p&gt;While attempting to animate an object, I ran into a bug where after setting the trigger to &amp;ldquo;state_2&amp;rdquo; it would go to &amp;ldquo;state_2&amp;rdquo;, and back again to &amp;ldquo;state_1&amp;rdquo;. It was really weird, and I had no clue why&amp;hellip;&lt;/p&gt;
&lt;p&gt;The first thing that comes to mind is &amp;ldquo;Exit time&amp;rdquo;. If that property is set on the animation transition, it will automatically leave the current state onto the destination state of that transition&amp;hellip; Nope, no exit state was being set.&lt;/p&gt;
&lt;p&gt;After fiddling around the code for a while, I found that I was using &lt;code&gt;SetTrigger&lt;/code&gt; on &amp;ldquo;state_1&amp;rdquo; while the object was still in &amp;ldquo;state_1&amp;rdquo;. Since I didn&amp;rsquo;t allow the transition to animate to itself, the trigger would be set, and later be triggered after we leave the state.&lt;/p&gt;
&lt;p&gt;The solution here is either to use &lt;code&gt;ResetTrigger&lt;/code&gt; to make sure no outstanding triggers remain, or in my case, I simply allowed the animation state to transition to itself. That made the trigger clear after being set twice.&lt;/p&gt;
&lt;p&gt;&lt;img alt="transition-settings" src="/images/transition-settings.png"&gt;&lt;/p&gt;
&lt;h3&gt;Atomic&lt;/h3&gt;
&lt;p&gt;As much as I tried, I couldn&amp;rsquo;t manipulate a property of a game object that had an animation controller manipulating the same property.. It&amp;rsquo;s annoying, but understandable, I guess&amp;hellip;&lt;/p&gt;
&lt;p&gt;What I mean is, if you wanted to animate the position and scale of an object, you can either tween them or use Unity&amp;rsquo;s animation system, right? Well, if you choose to use both for any reason, you can&amp;rsquo;t have both systems modify the scale or the position at the same time. You must either let Unity&amp;rsquo;s system animate the scale, and using tweening for the position, or vice versa.&lt;/p&gt;
&lt;h3&gt;Discrete&lt;/h3&gt;
&lt;p&gt;When setting up your animation states in the animation controller, you might want your animations to play discretely (separately) without any blending. Well, the thing is, Unity&amp;rsquo;s default animation settings add a certain amount of blending, depending on today&amp;rsquo;s weather.&lt;/p&gt;
&lt;p&gt;The gotcha here is, just make sure to open the transition settings again, and set the transition duration to 0 in order to disable animation blending, and have nice discrete animations.&lt;/p&gt;
&lt;p&gt;Obviously, that&amp;rsquo;s not always the case. For my animations, I&amp;rsquo;ve actually set the blending to full. So the animation actually happens in the transition rather than the animation state itself (if that makes any sense)&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Unity has really come a long way.. I&amp;rsquo;ve tried it a year and two years ago, and it&amp;rsquo;s nothing like it used to be. It has finally matured to the point of actually being usable to a certain degree&amp;hellip;&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t looked at Unity for a while, make sure to give it another shot!&lt;/p&gt;</content><category term="posts"></category><category term="unity"></category></entry><entry><title>Back Me Up!</title><link href="https://mazyod.com/blog/2016/07/01/back-me-up/" rel="alternate"></link><published>2016-07-01T05:05:05+00:00</published><updated>2016-07-01T05:05:05+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-07-01:/blog/2016/07/01/back-me-up/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The final post that concludes the series about game development is gonna be around the backend (server). It&amp;rsquo;s pretty big topic, but I figured I&amp;rsquo;d summarize it in one (probably) long post, so here it goes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/26/chewy-gui/"&gt;The GUI system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/28/rev-up-your-engine/"&gt;The game engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/29/quality-of-service/"&gt;The game services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The backend …&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The final post that concludes the series about game development is gonna be around the backend (server). It&amp;rsquo;s pretty big topic, but I figured I&amp;rsquo;d summarize it in one (probably) long post, so here it goes.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/26/chewy-gui/"&gt;The GUI system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/28/rev-up-your-engine/"&gt;The game engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/29/quality-of-service/"&gt;The game services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The backend&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Back Me Up!&lt;/h2&gt;
&lt;p&gt;Wait, why do we wanna bother with a backend? Can&amp;rsquo;t we just build a game and ship it without any backend whatsoever? .. Sure you can, but you&amp;rsquo;re talking about a seriously slim chance of success, as slim as flappy bird!&lt;/p&gt;
&lt;p&gt;Compared to most other games, flappy bird is one of the few which doesn&amp;rsquo;t rely on a backend. Angry birds, CoC, Candy Crush, .. You name it! If it has any of the features below, it needs some sort of backend support:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Achievements&lt;/li&gt;
&lt;li&gt;Leaderboards&lt;/li&gt;
&lt;li&gt;Matchmaking&lt;/li&gt;
&lt;li&gt;Push notifications&lt;/li&gt;
&lt;li&gt;User profiles&lt;/li&gt;
&lt;li&gt;&amp;hellip; etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now, if you really wanna be lean and mean, you should avoid developing a backend yourself. There are tons of services out there that provide you with basic features, which you may get away with if your game is simple enough. This list is far from exhaustive: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GameCenter&lt;/li&gt;
&lt;li&gt;Google Play Services&lt;/li&gt;
&lt;li&gt;&lt;a href="https://playfab.com"&gt;PlayFab&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://heroiclabs.com"&gt;Heroic Labs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.photonengine.com"&gt;Photon Engine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Personally, I&amp;rsquo;ve had my fair share of pain dealing with blackbox backends that leave you completely in the dark when it comes to how the server is managed. If you start growing or needing extra features .. Good luck with that! Sometimes you don&amp;rsquo;t need that, most likely (if your game is any good) you&amp;rsquo;ll want it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve gone through my share of pain and suffering with the backend, all the way from a &lt;a href="http://www.smartfoxserver.com/"&gt;Java based server&lt;/a&gt;, to a &lt;a href="https://mazyod.com/blog/2015/02/17/http-game-server-part-i/"&gt;python&lt;/a&gt; based &lt;a href="https://mazyod.com/blog/2015/02/24/http-game-server-part-ii/"&gt;server&lt;/a&gt; on &lt;a href="https://mazyod.com/blog/2015/03/01/http-game-server-part-iii/"&gt;GAE&lt;/a&gt;, to a &lt;a href="https://mazyod.com/blog/2015/05/05/http-game-server-the-rewrite/"&gt;C++ based madness server&lt;/a&gt;, and finally &amp;hellip; to &lt;a href="https://mazyod.com/blog/2016/05/22/alchemy/"&gt;Elixir-goodness&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve pretty much settled with Elixir, since with relatively minimal effort, I&amp;rsquo;ve written a full-featured realtime backend. Fully tested, with unit tests and integration tests. Moreover, stress tested like mad by the authors of the phoenix framework.&lt;/p&gt;
&lt;p&gt;Using Elixir for my game was perfect, since it finally allowed me to think about server from the clients perspective. &lt;/p&gt;
&lt;p&gt;Once a client connects to a server, we spawn a process to track that user. When that process dies, that means the user is disconnected! SO SIMPLE!! Do you want to add a retry and wait for the user to connect back again? SURE! All your work is done within that process.&lt;/p&gt;
&lt;p&gt;Once the user starts interacting with our backend, we send the user&amp;rsquo;s process id (pid) to workers which do stuff. For example, the matchmaker worker will take a bunch of user processes then match them against each other based on the relative rating for each player.&lt;/p&gt;
&lt;p&gt;Besides the workers, we also have &amp;ldquo;stateful&amp;rdquo; processes, which hold a shared state between one or more user process. For example, we spawn a &amp;ldquo;room state&amp;rdquo; process, and add the user to it. Once another user process joins, we close that &amp;ldquo;room state&amp;rdquo; process, and spawn a &amp;ldquo;game state&amp;rdquo; process, add the players there, and now they can proceed playing the game!!! It&amp;rsquo;s is so eloquent I can&amp;rsquo;t help but keep admiring how superior it is compared to every other crappy (yet popular) framework out there. &lt;em&gt;ehm&lt;/em&gt; Django. &lt;em&gt;ehm&lt;/em&gt; Rails.&lt;/p&gt;
&lt;p&gt;So, with that, really, it was a piece of cake to write an auth system, leaderboards, game system, &amp;ldquo;referee&amp;rdquo; worker, matchmaker, &amp;hellip; etc. All that makes up my game city! It&amp;rsquo;s really more of a city at this point rather than a server.&lt;/p&gt;
&lt;p&gt;With the features easily implemented, since Elixir is a productivity focused language, we also gain scalability for free. I can, at any point in time, break my backend workers into Elixir applications, push them to different servers, and have a decentralized Elixir backend, which I can easily then scale and upgrade in a super fine-grain way.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Phew!&lt;/em&gt; Enough with the Elixir fanboyism! Time to close off this topic and head home!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you&amp;rsquo;re looking for a backend for your game, make sure you test a &amp;ldquo;vertical slice demo&amp;rdquo; on it. Trust me on this one. Don&amp;rsquo;t delay crucial features from the backend thinking that you&amp;rsquo;ll get back to it later .. That spells disaster.&lt;/p&gt;
&lt;p&gt;If you can easily implement the &amp;ldquo;vertical slice&amp;rdquo; demo on the backend easily enough, then you&amp;rsquo;re doing it wrong indie chum. Unless you really wanna focus on the backend, like it is the core of your game, or you have some super weird requirement, just stick with a simple solution. Even a custom backend can still be simple enough to develop!&lt;/p&gt;</content><category term="posts"></category><category term="game-development"></category></entry><entry><title>Quality of Service</title><link href="https://mazyod.com/blog/2016/06/29/quality-of-service/" rel="alternate"></link><published>2016-06-29T19:20:13+00:00</published><updated>2016-06-29T19:20:13+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-29:/blog/2016/06/29/quality-of-service/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As highlighted by the nifty list below, this is part III of the four part series about game development!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/26/chewy-gui/"&gt;The GUI system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/28/rev-up-your-engine/"&gt;The game engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The game services&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/07/01/back-me-up/"&gt;The backend system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I apologize for the ambiguous, possibly inaccurate, name &amp;ldquo;game services&amp;rdquo;. I just didn&amp;rsquo;t know what to call …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;As highlighted by the nifty list below, this is part III of the four part series about game development!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/26/chewy-gui/"&gt;The GUI system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/28/rev-up-your-engine/"&gt;The game engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The game services&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/07/01/back-me-up/"&gt;The backend system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I apologize for the ambiguous, possibly inaccurate, name &amp;ldquo;game services&amp;rdquo;. I just didn&amp;rsquo;t know what to call these features, even though we use them in every single game we ever make.&lt;/p&gt;
&lt;p&gt;The game services I am referring to are the supporting features we need around our game. JSON parsing, persistence, networking, &amp;hellip; etc. These aren&amp;rsquo;t necessarily provided by the engine (I think it should never be), but we should easily find and integrate a third-party plug-in that provides the needed services.&lt;/p&gt;
&lt;p&gt;So, let&amp;rsquo;s see exactly what services we need, and how our game engine can help with that.&lt;/p&gt;
&lt;h2&gt;Quality of Service&lt;/h2&gt;
&lt;p&gt;For my development needs, I needed the ability to access these basic services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Persistence&lt;/li&gt;
&lt;li&gt;Websocket networking&lt;/li&gt;
&lt;li&gt;HTTP GET, POST requests&lt;/li&gt;
&lt;li&gt;JSON parsing&lt;/li&gt;
&lt;li&gt;Analytics&lt;/li&gt;
&lt;li&gt;IAP (In app purchases)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing fancy, really. Other games might require much more than this, including things like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TCP/UDP networking&lt;/li&gt;
&lt;li&gt;Compression&lt;/li&gt;
&lt;li&gt;Encryption&lt;/li&gt;
&lt;li&gt;&amp;hellip; etc&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you highlight your needed services, just take a stab at implementing a basic game that simply exercises using them. For example, if you use an engine like Cocos2d-x, you&amp;rsquo;ll find it cumbersome to integrate third party libraries for IAP, and JSON serialization is painful with C++ (especially so since they chose rapidJSON over JsonCPP).&lt;/p&gt;
&lt;p&gt;But still, if you take a step back and realize how customizable Cocos2d-x is, you can simply nuke the services it provides for you, and integrate your own from the vast open source libraries in the C++ landscape.&lt;/p&gt;
&lt;p&gt;That is, until you turn around and peek at what the Unity people are doing. You just wanna take a brief look, and you see them partying and having fun! You&amp;rsquo;re now like, &amp;ldquo;WTH?! Game development is hard! How come these people are celebrating at such a crucial time??&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The thing is, Unity pretty much solved the services issue by having an Asset Store. Developers had an incentive to share their reusable services through a market place that provided them with an alternative source of income, so why not?&lt;/p&gt;
&lt;p&gt;No matter how good an engine gets, it&amp;rsquo;ll fail horribly if it tries to be a &amp;ldquo;do-it-all&amp;rdquo;, kitchen-sink type of deal. Developers come in many flavors, and the best way to keep them happy is to allow them to bring their own tools and technologies they love, instead of forcing everything down their throat.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This one was brief, as it should be, and it concludes the client-side part! In the next post, we will switch over to the server, and see how game development looks from that angle.&lt;/p&gt;</content><category term="posts"></category><category term="game-development"></category></entry><entry><title>Rev Up Your Engine</title><link href="https://mazyod.com/blog/2016/06/28/rev-up-your-engine/" rel="alternate"></link><published>2016-06-28T02:59:55+00:00</published><updated>2016-06-28T02:59:55+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-28:/blog/2016/06/28/rev-up-your-engine/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the second article in this game development series overway, I would like to shed some light on the aspects that make up the game engine. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overview:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/26/chewy-gui/"&gt;The GUI system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The game engine&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/29/quality-of-service/"&gt;The game services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/07/01/back-me-up/"&gt;The backend system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The term &amp;ldquo;Game Engine&amp;rdquo; is arguably not well defined. For …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the second article in this game development series overway, I would like to shed some light on the aspects that make up the game engine. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overview:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/26/chewy-gui/"&gt;The GUI system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The game engine&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/29/quality-of-service/"&gt;The game services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/07/01/back-me-up/"&gt;The backend system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The term &amp;ldquo;Game Engine&amp;rdquo; is arguably not well defined. For example, I can call the following code a game engine:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
  &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read_next&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;render&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="nb"&gt;print&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;y&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code above has a run loop, renders some output, and can be used to make a simple game thingie .. I think.&lt;/p&gt;
&lt;p&gt;Anyway, back to the point, a Game Engine can be graphical, with 2D and/or 3D support, or it can be text based, sound based, or any other sort of output. What I&amp;rsquo;m gonna be focusing on is a typical 2D/3D game engine, and I want to focus specifically on the graphics rendering aspects, and not other side features, like networking, persistence, memory management and whatnot.. That comes later.&lt;/p&gt;
&lt;h2&gt;Revving Up&lt;/h2&gt;
&lt;p&gt;The declaimer, once again, is that I&amp;rsquo;ll be exploring these gaming topics solely from the perspective of my game, and nothing else. So, let&amp;rsquo;s things underway.&lt;/p&gt;
&lt;p&gt;So my game is just a checkers thingie. Moreover, I&amp;rsquo;m not planning on adding any exciting features on top of the core experience, that is playing the damn game. It would be nice if the piece would become a pacman thingie, and walk around eating other pieces, for example&amp;hellip; That&amp;rsquo;s what we call &amp;ldquo;scope creep&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;So, I really need any engine that will give me the ability to show sprites or 3D models if possible, and allow me to animate those objects around using a jump animation. Not surprisingly, most engines fit this requirement (not my previous python game engine tho, mind you).&lt;/p&gt;
&lt;p&gt;Another important requirement was actually the interaction. Not many game engines provide sleek and simple interaction system that handles touches and clicks in a simple manner. Unity does quite well on this end as well, so no complaints about it there.&lt;/p&gt;
&lt;p&gt;My final, super-weird requirement, which is one of the main reasons this game is delayed as much as it is, is C/C++ support! I really needed a game engine that allowed me to plug-in my game logic and AI, which is written in C. Unity used to require a pro license for that, which pushed me away from it. With Unity 5, it&amp;rsquo;s available for all users, and they have a new plug-in inspector thingie that allows you easily create and target plug-ins for different platforms! It sure came a long way.&lt;/p&gt;
&lt;p&gt;So, with a bit of SWIG and python magic, as &lt;a href="https://mazyod.com/blog/2016/02/16/swig-swag/"&gt;highlighted here&lt;/a&gt;, Unity was a go!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Sorry for the lack of excitement here, a topic about game engines should really be much more thrilling, lol. Again, my game is super simple on the gaming side, so learn something different for a change!&lt;/p&gt;</content><category term="posts"></category><category term="game-development"></category></entry><entry><title>Chewy GUI</title><link href="https://mazyod.com/blog/2016/06/26/chewy-gui/" rel="alternate"></link><published>2016-06-26T05:46:36+00:00</published><updated>2016-06-26T05:46:36+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-26:/blog/2016/06/26/chewy-gui/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There is always something to post about when it comes to game development it&amp;rsquo;s so vast!! So, this is a post just to talk about how vast it can be! (think meta).&lt;/p&gt;
&lt;p&gt;Look, before you get all intimidated on me, game development can be as simple as drag …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There is always something to post about when it comes to game development it&amp;rsquo;s so vast!! So, this is a post just to talk about how vast it can be! (think meta).&lt;/p&gt;
&lt;p&gt;Look, before you get all intimidated on me, game development can be as simple as drag and drop &amp;hellip; Not even writing a single line of code, &lt;strong&gt;and&lt;/strong&gt; still be &lt;a href="https://www.buildbox.com/number-one-iphone-app-made-with-buildbox/"&gt;a world-wide success&lt;/a&gt;. It can also be an insanely huge collaborative effort that takes years, thousands of man-hours, and cost &lt;a href="https://en.wikipedia.org/wiki/List_of_most_expensive_video_games_to_develop"&gt;up to half a billion dollar to make ._.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;So, even though my game is obviously on the lower end of the spectrum, it&amp;rsquo;s not trivial, and has tons of features that makes it exciting to develop as well. Since this blog is concerned with software development, I&amp;rsquo;ll only cover that part.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s break it down, shall we?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Overview:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The GUI system&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/28/rev-up-your-engine/"&gt;The game engine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/06/29/quality-of-service/"&gt;The game services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mazyod.com/blog/2016/07/01/back-me-up/"&gt;The backend system&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Chewy GUI&lt;/h2&gt;
&lt;p&gt;My game falls into that group of games which are UI-heavy. For these games, a GUI system can either make or break the game. A classical example are RPGs. &lt;/p&gt;
&lt;p&gt;Imagine an RPG game without a proper GUI system &amp;hellip; You probably can&amp;rsquo;t, because if it had a horrible GUI system, you probably wouldn&amp;rsquo;t ever hear about it because of hard it failed.&lt;/p&gt;
&lt;p&gt;&lt;img alt="FF-VII GUI" src="/images/ff-vii-gui.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The key here is to &lt;strong&gt;avoid fancy crap!&lt;/strong&gt; The Final Fantasy GUI system is super simple, and has been reused since Final Fantasy I!! It is one of the most renowned and celebrated series of all time, and since you spend arguably most of your time on the GUI system, they must have done it right.&lt;/p&gt;
&lt;p&gt;Since my game is heavy on GUI, I had to make sure I choose a game engine that will not fail me on that front. Some of the things you wanna look for in a game engine you&amp;rsquo;re gonna use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WYSIWYG GUI editor&lt;/li&gt;
&lt;li&gt;Adaptive to screen resolutions&lt;/li&gt;
&lt;li&gt;Easy GUI navigation&lt;/li&gt;
&lt;li&gt;Localization support&lt;/li&gt;
&lt;li&gt;Out-of-box widgets (text fields, labels, buttons, &amp;hellip; etc)&lt;/li&gt;
&lt;li&gt;Simple animation support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My favorite engine until now, Cocos2d, fails horribly when it comes to GUI development, unfortunately. The lack of a usable editor, as well as the constant turmoil their GUI system goes through made me move away from it.&lt;/p&gt;
&lt;p&gt;My eyes fell on other open-source game engines, such as LibGDX and Godot, but unfortunately, even those (at that time) weren&amp;rsquo;t usable for indie development (we are still talking about GUI side of things). I didn&amp;rsquo;t want to spend more time digging around other game engines, so I just decided to make a deal with the devil (aka Unity).&lt;/p&gt;
&lt;p&gt;Honestly, for an engine as established as Unity, it was still very annoying to work with their new GUI system. I had issues mostly with tweening and implementing a proper navigation system&amp;hellip; I couldn&amp;rsquo;t waste my time here, though, so I hired some else to take care of the GUI stuff.&lt;/p&gt;
&lt;p&gt;The developers I hired were more comfortable working with NGUI than the native uGUI system shipping with Unity, which is a bit annoying for me, but they really breezed through the GUI tasks, so I didn&amp;rsquo;t have a reason to complain.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verdict&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, Unity is the ultimate answer for GUI games? Not at all. If I were to start over, I&amp;rsquo;ll probably shock you &amp;hellip; I&amp;rsquo;d use ReactNative or some other app framework!! My game is so heavy on GUI, it makes less sense to use a game engine and more sense to use a cross-platform app framework! It would be super easy to develop the app, and once I reach the game part, I can just use WebGL!&lt;/p&gt;
&lt;p&gt;Well, I know, that won&amp;rsquo;t be fun at all, but I really believe it would be the best choice. Also, I think there might be other game engines that would be a better fit, possibly BuildBox, MonoGame, or some other simpler game engine (as long as it is easy to develop GUI stuff!).&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;As far as my current game goes, I&amp;rsquo;ve optimized the backend development, the service, game logic, and even the art! The only pain point left I have is a proper GUI system, and even though what I currently have is kinda good, it&amp;rsquo;s far from ideal .. Ideally, I don&amp;rsquo;t have to hire anyone just to do GUI work. Ideally, GUI would be so simple, I don&amp;rsquo;t have to write a post about it (or, at least, it can be a subtopic of the game engine).&lt;/p&gt;
&lt;p&gt;Look forward to future posts about the rest of the topics!&lt;/p&gt;</content><category term="posts"></category><category term="game-development"></category></entry><entry><title>Phoenix 1.2.0</title><link href="https://mazyod.com/blog/2016/06/23/phoenix-120/" rel="alternate"></link><published>2016-06-23T06:24:58+00:00</published><updated>2016-06-23T06:24:58+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-23:/blog/2016/06/23/phoenix-120/</id><summary type="html">&lt;p&gt;This will be a quick one, since I didn&amp;rsquo;t really upgrade to Phoenix v1.2.0, unfortunately&amp;hellip; Why, why not?!&lt;/p&gt;
&lt;p&gt;The main reason I was eager to upgrade was the new Presence feature. It will really streamline my code, and allow me to easily implement the monitoring stuff I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This will be a quick one, since I didn&amp;rsquo;t really upgrade to Phoenix v1.2.0, unfortunately&amp;hellip; Why, why not?!&lt;/p&gt;
&lt;p&gt;The main reason I was eager to upgrade was the new Presence feature. It will really streamline my code, and allow me to easily implement the monitoring stuff I mentioned in the previous post. Also, my tests are getting slow, so having the ecto async goodness would be great as well.&lt;/p&gt;
&lt;p&gt;The reason I didn&amp;rsquo;t upgrade is because I&amp;rsquo;ve tried to, and it didn&amp;rsquo;t work out.&lt;/p&gt;
&lt;p&gt;First off, after the upgrade, I ran my tests, and got a whole lot of long error stacktraces on my console. I&amp;rsquo;ve included a few at the bottom. The first one I tackled was the &lt;code&gt;FunctionClauseError&lt;/code&gt; related to the &lt;code&gt;handle_info&lt;/code&gt; stuff. After spending about an hour at the Elixir slack channel, turns out it was a bug in the &lt;code&gt;db_connection&lt;/code&gt; library.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s not too bad, but seeing that this is just one error, and I now see at least three more different ones, I just can&amp;rsquo;t spend the time to dig into each and every one!&lt;/p&gt;
&lt;p&gt;It probably makes sense at this point not to upgrade a sufficiently complex application, and wait for the release to stabilize. I have a new project in Elixir, tho, and it&amp;rsquo;s using v1.2.0 without issues. This is because I can easily avoid troublesome patterns in the new app, but it would take forever to migrate the old app.&lt;/p&gt;
&lt;p&gt;Just a quick example of a &amp;ldquo;troublesome&amp;rdquo; pattern, that is spinning off GenServers and processes that interact with the DB. Apparently, the new Ecto sandbox stuff is nice and all, but quite restrictive. To properly use it, you either have to do it right from the get-go, or refactor your whole implementation.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s about it! Here are some relevant logs:&lt;/p&gt;
&lt;p&gt;This is the log of the issue &lt;a href="https://github.com/elixir-ecto/db_connection/pull/47"&gt;related to this pr&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;03:18:08.674 [error] GenServer #PID&amp;lt;0.346.0&amp;gt; terminating
** (FunctionClauseError) no function clause matching in Socks.UserState.handle_info/2
    (socks) web/state/user_state.ex:16: Socks.UserState.handle_info({#Reference&amp;lt;&amp;gt;, {:ok, {#PID&amp;lt;&amp;gt;, #Reference&amp;lt;&amp;gt;}, Ecto.Adapters.SQL.Sandbox.Connection, {Postgrex.Protocol, %Postgrex.Protocol{}, false}}}, %{user: %Socks.User{}})
    (stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:681: :gen_server.handle_msg/5
    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This one is a completely random DBConnection error that doesn&amp;rsquo;t make any sense to me. I&amp;rsquo;m not sure about it, so I can&amp;rsquo;t really open an issue on Github&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; One of the Ecto developers told me it&amp;rsquo;s a bug already fixed on master.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;03:46:11.179 [error] Postgrex.Protocol (#PID&amp;lt;0.218.0&amp;gt;) disconnected: ** (DBConnection.ConnectionError) client #PID&amp;lt;0.270.0&amp;gt; exited: an exception was raised:
    ** (FunctionClauseError) no function clause matching in Ecto.Adapters.SQL.Sandbox.Pool.disconnect/4
        (ecto) lib/ecto/adapters/sql/sandbox.ex:371: Ecto.Adapters.SQL.Sandbox.Pool.disconnect({#PID&amp;lt;0.210.0&amp;gt;, #PID&amp;lt;0.218.0&amp;gt;, {#PID&amp;lt;0.218.0&amp;gt;, #Reference&amp;lt;0.0.4.38&amp;gt;}}, %DBConnection.ConnectionError{message: &amp;quot;owner #PID&amp;lt;0.269.0&amp;gt; exited while client #PID&amp;lt;0.272.0&amp;gt; is still running with: shutdown&amp;quot;}, {Postgrex.Protocol, %Postgrex.Protocol{buffer: &amp;quot;&amp;quot;, connection_id: 20156, null: nil, parameters: #Reference&amp;lt;0.0.1.1465&amp;gt;, postgres: :transaction, queries: 163889, sock: {:gen_tcp, #Port&amp;lt;0.7617&amp;gt;}, timeout: 15000, transactions: :naive, types: 139307}, false}, [timeout: :infinity, repo: Socks.Repo, sandbox_pool: DBConnection.Poolboy, ownership_pool: Ecto.Adapters.SQL.Sandbox.Pool, pool_timeout: 5000, adapter: Ecto.Adapters.Postgres, username: &amp;quot;xxx&amp;quot;, password: &amp;quot;xxx&amp;quot;, database: &amp;quot;xxx&amp;quot;, hostname: &amp;quot;xxx&amp;quot;, pool: DBConnection.Ownership])
        (db_connection) lib/db_connection/ownership/proxy.ex:234: DBConnection.Ownership.Proxy.down/2
        (stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
        (stdlib) gen_server.erl:681: :gen_server.handle_msg/5
        (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, many people have been running into this, but it seems the only way to avoid it is to properly manage your access to the DB and make sure all transactions are complete within the test time frame?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;04:40:47.009 [error] GenServer #PID&amp;lt;0.274.0&amp;gt; terminating
** (stop) exited in: GenServer.call(#PID&amp;lt;0.267.0&amp;gt;, {:checkout, #Reference&amp;lt;0.0.2.2087&amp;gt;, true, 15000}, 5000)
    ** (EXIT) shutdown: &amp;quot;owner #PID&amp;lt;0.266.0&amp;gt; exited with: shutdown&amp;quot;
    (db_connection) lib/db_connection/ownership/proxy.ex:32: DBConnection.Ownership.Proxy.checkout/2
    (db_connection) lib/db_connection.ex:716: DBConnection.checkout/2
    (db_connection) lib/db_connection.ex:623: DBConnection.run/3
    (db_connection) lib/db_connection.ex:464: DBConnection.prepare_execute/4
    (ecto) lib/ecto/adapters/sql.ex:228: Ecto.Adapters.SQL.sql_call/6
    (ecto) lib/ecto/adapters/sql.ex:400: Ecto.Adapters.SQL.execute_and_cache/7
    (ecto) lib/ecto/repo/queryable.ex:127: Ecto.Repo.Queryable.execute/5
    (ecto) lib/ecto/repo/queryable.ex:40: Ecto.Repo.Queryable.all/4
    (ecto) lib/ecto/repo/queryable.ex:72: Ecto.Repo.Queryable.one!/4
    (socks) web/state/user_state.ex:20: Socks.UserState.handle_info/2
    (stdlib) gen_server.erl:615: :gen_server.try_dispatch/4
    (stdlib) gen_server.erl:681: :gen_server.handle_msg/5
    (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="posts"></category><category term="phoenix"></category></entry><entry><title>Elixir Metrics</title><link href="https://mazyod.com/blog/2016/06/22/elixir-metrics/" rel="alternate"></link><published>2016-06-22T05:42:02+00:00</published><updated>2016-06-22T05:42:02+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-22:/blog/2016/06/22/elixir-metrics/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Yet another post about the Elixir game server, and this time it&amp;rsquo;s about how I should be monitoring the server metrics, such as the game rooms, matchmaking queues, and actual games&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Ideally Speaking&lt;/h2&gt;
&lt;p&gt;I guess, the ideal situation I&amp;rsquo;d like to be in is to have a …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Yet another post about the Elixir game server, and this time it&amp;rsquo;s about how I should be monitoring the server metrics, such as the game rooms, matchmaking queues, and actual games&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Ideally Speaking&lt;/h2&gt;
&lt;p&gt;I guess, the ideal situation I&amp;rsquo;d like to be in is to have a time machine that would allow me to go back in time, and learn web development instead of wasting all that time with C++ and Java.&lt;/p&gt;
&lt;p&gt;No, really. Ideally speaking, having a properly built website is awesome, but it seems like a huge investment everytime I give it a shot. You see, for a person without much frontend development knowledge, it gets intimidating which framework one should use, which template, which IDE, and so on.&lt;/p&gt;
&lt;p&gt;Also, there is the simple reality that I am not familiar with the Phoenix JavaScript frontend library. All this meant to me that I&amp;rsquo;d be spending a full week to get something respectable out the door .. There is no way I got time for that.&lt;/p&gt;
&lt;h2&gt;Hacking a Solution&lt;/h2&gt;
&lt;p&gt;Apparently, one of the services I already have integrated, namely DataDog, has some sort of custom metric tracking. With a community contributed Elixir library, it was quite simple to get up and running with something small and simple.&lt;/p&gt;
&lt;p&gt;With custom metrics, you can have your backend report various data points, such as counters, gouges, histograms, &amp;hellip; and so on. The counter sounded perfect! &amp;hellip; Except, it wasn&amp;rsquo;t perfect at all.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/DataDog/dd-agent/issues/659"&gt;According to this Github issue&lt;/a&gt;, datadog does some sort of normalization on the data sent, and you end up with vague numbers that sort of give you a clue of the general &amp;ldquo;rate&amp;rdquo; and not &amp;ldquo;count&amp;rdquo; of the metric you are monitoring&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, as an example, I had my &lt;code&gt;:room_store&lt;/code&gt; process emit a &lt;code&gt;statsd.increment&lt;/code&gt; event whenever a new room was opened, and &lt;code&gt;statsd.decrement&lt;/code&gt; event when a room was closed &amp;hellip; What I ended up with were fractions, since the numbers where divided over a regular interval, and are not aggregated. Doesn&amp;rsquo;t solve my issue.&lt;/p&gt;
&lt;h2&gt;MOAR Services&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve touched upon LogEntries in the past and how it seemed like an exciting service to try out, but never really got to that, so .. I think it&amp;rsquo;s time. Perhaps the answer lies with this service.. Maybe, just maybe, I can finish this task in a few minutes &amp;hellip; Let&amp;rsquo;s see.&lt;/p&gt;
&lt;p&gt;Doesn&amp;rsquo;t cut it for me, unfortunately&amp;hellip; The minimum plan you must get to unlock real-time analytics will set you back at least $1200/yr. Maybe it&amp;rsquo;s worthwhile, but for something so uncertain as a game that&amp;rsquo;s being developed for half a decade &amp;hellip; Moving on!&lt;/p&gt;
&lt;h2&gt;iOS&lt;/h2&gt;
&lt;p&gt;I seriously considered just wiring together an iOS app, since that&amp;rsquo;s what I am most comfortable with. The problem is, this approach doesn&amp;rsquo;t scale. After writing an iOS app, I&amp;rsquo;ll need to run it as a daemon and constantly monitor the numbers and metrics, which just doesn&amp;rsquo;t work for iOS.&lt;/p&gt;
&lt;p&gt;Yes, Swift now runs on Linux, but that doesn&amp;rsquo;t mean it&amp;rsquo;s feasible to go and download the Swift 3 toolchain, set up all this headache, and hope there is a compatible websocket/phoenix library out there. That just doesn&amp;rsquo;t work.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I really don&amp;rsquo;t have a choice, my only option is as plain as day. Whatever it takes, I must implement an admin dashboard on top of my backend that will show me all these metrics. It can be the most basic, ugly looking hack every conceived, but it will get the job done and set us of the right foot!&lt;/p&gt;
&lt;p&gt;Time for Brunch!&lt;/p&gt;</content><category term="posts"></category><category term="elixir"></category></entry><entry><title>Firebase Service</title><link href="https://mazyod.com/blog/2016/06/19/firebase-service/" rel="alternate"></link><published>2016-06-19T05:24:02+00:00</published><updated>2016-06-19T05:24:02+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-19:/blog/2016/06/19/firebase-service/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s tons of fun running your own thing, working on your ideas and projects .. That is, until you&amp;rsquo;re broke. Now, if your thing makes enough money for you to sustain and grow, then kudos, you&amp;rsquo;ve made it. For the rest of us stuck in the chasm …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s tons of fun running your own thing, working on your ideas and projects .. That is, until you&amp;rsquo;re broke. Now, if your thing makes enough money for you to sustain and grow, then kudos, you&amp;rsquo;ve made it. For the rest of us stuck in the chasm, we need an alternative money source.&lt;/p&gt;
&lt;p&gt;The common knowledge where I&amp;rsquo;m from is to take a government job, slack, and work on your own thing. You see, this doesn&amp;rsquo;t cut it for me. Why would one deliberately choose to waste one&amp;rsquo;s time with stuff trivial matters? The ideal scenario is a part-time job as a programmer that also pays enough for me to sustain. Luckily, I found such job.&lt;/p&gt;
&lt;p&gt;So, while I focus on my own projects most of the time, I then get to switch gears and work on other challenging projects. These projects give me a lot of content to write about, which is also great for this blog! So, for today&amp;rsquo;s post, we&amp;rsquo;ll be covering the aspects of writing a backend service that syncs with Firebase.&lt;/p&gt;
&lt;p&gt;The idea is simple:&lt;/p&gt;
&lt;p&gt;Decouple the client apps from the backend by creating a micro-service that syncs the legacy backend&amp;rsquo;s database to firebase. The client applications will then just use firebase to access the data.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s first take a deeper look at these design requirements.&lt;/p&gt;
&lt;h2&gt;µService&lt;/h2&gt;
&lt;p&gt;First off, I&amp;rsquo;d like to take a closer look at the root problem that prompted the need for this task.&lt;/p&gt;
&lt;h3&gt;Root of the Problem&lt;/h3&gt;
&lt;p&gt;The main issue is that the startup has relatively high engineering work to be done, and not enough engineers to carry out the tasks. If we had a sufficient supply of engineers, we wouldn&amp;rsquo;t be bothering with this. So, to mitigate this issue, we decided it would be best to cut corners where-ever possible to reduce the engineering overhead involved.&lt;/p&gt;
&lt;p&gt;Looking at our setup, and also due to my bias as the iOS engineer in the team, I realized the biggest drain of resources (by far) was the maintenance of two native mobile applications (iOS/Android). For a relatively simple app, I figured our first priority was to seek parity between these platforms.&lt;/p&gt;
&lt;h3&gt;iOS 💘 Android&lt;/h3&gt;
&lt;p&gt;In order to unify the development process on these platforms, we must unify the way we consume the backend API and sync data, as well as unify the GUI development process. Due to our lack of expertise in cross-platform technologies, such as NativeScript and ReactNative, we shied off from going all out with those from the start. We figured we can do some initial work to achieve partial parity first, which puts us in a better position to decide later. This is where Firebase comes in.&lt;/p&gt;
&lt;p&gt;Firebase offers cross-platform tools to manage and deal with common services your application might need, such as datastore, crash reporting, analtyics, &amp;hellip; etc. Utilizing Firebase would help us achieve some partial parity between the current code bases, and then, we can move to something like ReactNative when we&amp;rsquo;re ready.&lt;/p&gt;
&lt;h3&gt;Detailed Design&lt;/h3&gt;
&lt;p&gt;Currently, we have a very basic and common API that is being consumed by the client applications. After logging in and acquiring a secure token, you authenticate each API call thereafter with that token. There is one API call for now, and it is to retrieve the &amp;ldquo;user data&amp;rdquo; on a specific &amp;ldquo;date&amp;rdquo;. Something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;/api/v1.1/user_data/YYYYMMDD/&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As things are right now, the client app wakes up when a push notification is received signaling new data is available. The app then pulls the latest user data and adds it to the local store. The user also has the ability to browse old data, and another API call is issued if that data is missing.&lt;/p&gt;
&lt;p&gt;After thinking of many ways to go about this, I had to prioritize the following constraint:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Build a micro-service completely transparent the to the current backend.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What?! Impossible! How can that be?&lt;/p&gt;
&lt;p&gt;Well, once the user logs in on the client app, the client app simply pushes that token to the new micro-service. The service then stores that token, and continues to sync its data on daily basis. If the user decides to browse an old entry, a &amp;ldquo;forced update&amp;rdquo; request is pushed to the micro-service, which attempts to retrieve the data and write it to Firebase. At that moment, the client app will receive the Firebase data update!&lt;/p&gt;
&lt;p&gt;With this design at hand, there is absolutely no need to change a single line in the current legacy backend! Banzai!&lt;/p&gt;
&lt;p&gt;So, let&amp;rsquo;s write it! How hard can it be?&lt;/p&gt;
&lt;p&gt;Well, this is actually my second time writing a Firebase service. The first time I wrote one, it was written in Elixir. It was so simple, I didn&amp;rsquo;t feel the need to blog about it &amp;hellip; However, this time around, Firebase has changed a lot! Let&amp;rsquo;s see what these changes brought us, and what it means for our micro-service.&lt;/p&gt;
&lt;h2&gt;Shiny Fire&lt;/h2&gt;
&lt;p&gt;As we all know, Firebase has been overhauled recently with SDK v3. Google took Firebase to a whole new level (not necessarily a good thing).&lt;/p&gt;
&lt;h4&gt;The Good&lt;/h4&gt;
&lt;p&gt;I have to give Google credit for bundling push notification services, crash reporting, storage, and a bunch of other goodies with Firebase. For this job, I needed to migrate away from Parse as well. So, with these new goodies, Firebase has become an excellent alternative.&lt;/p&gt;
&lt;h4&gt;The Bad&lt;/h4&gt;
&lt;p&gt;Firebase got dragged into Google&amp;rsquo;s auth system&amp;hellip; DAMN IT!!! This part is really frustrating because Google&amp;rsquo;s auth system is so friggin&amp;rsquo; complicated and convoluted, you can&amp;rsquo;t make a single auth call without downloading 10 libraries, and reading 50 pages of docs.... It&amp;rsquo;s really annoying.&lt;/p&gt;
&lt;p&gt;No matter how challenging this new Firebase system is, the task has been set. The task shall be carried out!&lt;/p&gt;
&lt;h3&gt;Carrying out the Task&lt;/h3&gt;
&lt;p&gt;I really love Python, and clinged on the possibility of using it till the end, but without avail. Without going into too much detail, let&amp;rsquo;s say I was better off writing this micro-service in NodeJs.&lt;/p&gt;
&lt;p&gt;Indeed, with the NodeJs library Firebase has, it was super simple to get started with manipulating the Firebase datastore. By following the NodeJs getting started guide on Heroku as well, I was able to finalize the service prototype within a day&amp;rsquo;s worth of work.&lt;/p&gt;
&lt;p&gt;It would be interesting to perhaps explore the details of this micro-service and how it works, but for now, I feel it&amp;rsquo;s quite mundane. Besides, I am already way beyond the limit for this article!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Writing JS code wasn&amp;rsquo;t all that bad. It was a nice change. Sure, I wasn&amp;rsquo;t able to find a good way to format string, and I had to import 10 libraries to write simple stuff, but at the end, the code was quite neat and readable. This reduces my &amp;ldquo;Languages that should 🔥&amp;rdquo; down by one. Topping that list is, of course, PHP.&lt;/p&gt;</content><category term="posts"></category><category term="firebase"></category></entry><entry><title>See Windows</title><link href="https://mazyod.com/blog/2016/06/16/see-windows/" rel="alternate"></link><published>2016-06-16T05:46:36+00:00</published><updated>2016-06-16T05:46:36+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-16:/blog/2016/06/16/see-windows/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In this widely generic programming post, I&amp;rsquo;d like to go over the experience of building a C dynamic library (DLL) on windows. The reason I&amp;rsquo;m interested in building for windows is because my game&amp;rsquo;s logic is written in C, and my new programmer is running Unity …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In this widely generic programming post, I&amp;rsquo;d like to go over the experience of building a C dynamic library (DLL) on windows. The reason I&amp;rsquo;m interested in building for windows is because my game&amp;rsquo;s logic is written in C, and my new programmer is running Unity on windows. To properly run the game on windows, he needs a version of the game logic library targeted to windows. So annoying!&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;p&gt;To my great fortune, I had actually installed a VM manager recently, called &lt;a href="https://veertu.com/"&gt;veertu&lt;/a&gt;. With this app, I had a quick and easy solution to quickly run VMs running windows, ubuntu, &amp;hellip; etc.&lt;/p&gt;
&lt;p&gt;With that, I ran windows 10 installation, and using Github for Windows, Microsoft visual studio, Unity, and SWIG installed, the environment was all set.&lt;/p&gt;
&lt;p&gt;Using Github app made it a breeze to quickly clone the game logic repo into the VM. After that, I quickly downloaded and ran swig to regenerate the C wrapper. I am not sure if that is required to be generated separately on each platform, but that&amp;rsquo;s what I did anyway.&lt;/p&gt;
&lt;p&gt;Finally, it was time to figure out how to build this DLL!&lt;/p&gt;
&lt;h2&gt;Windows DLLs&lt;/h2&gt;
&lt;p&gt;After meaningless research and reading on how to build a C DLL on windows, I launched Microsoft Visual Studio and stared experimenting. The thing that worked was actually choosing &amp;ldquo;Command line application&amp;rdquo;, and selecting &amp;ldquo;DLL&amp;rdquo; on the next screen&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;WHY IN THE NAME OF BILL GATES IS DLL UNDER COMMAND LINE APPLICATIONS?!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So, anyway, I chose &amp;ldquo;export symbols&amp;rdquo;, and leaved all other options unchecked, and that created the project (or solution, as it is called in MCVS).&lt;/p&gt;
&lt;p&gt;After losing hope on figuring out how to import a folder into the solution, I simply dragged all files from windows explorer into the MCSV project. After those were added, I got a bunch of errors because of invalid includes.&lt;/p&gt;
&lt;p&gt;Apparently, I had structured my imports cleanly using:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;LibName/Directory/File.h&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You see, these angle bracket header includes indicate that the compile will &amp;ldquo;know&amp;rdquo; about the location of the &amp;ldquo;LibName&amp;rdquo; directory, but in MCSV, it doesn&amp;rsquo;t. I had no idea how to point the compiler to search for header files in &amp;ldquo;LibName&amp;rdquo;, so I just renamed all the includes to be relative imports:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;Directory/File.h&amp;quot;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;../File.h&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That resolved the include issues, and surprisingly enough, the DLL was built successfully! That was the least painful build experience I&amp;rsquo;ve had so far, so I&amp;rsquo;m not complaining about the few hurdles above.&lt;/p&gt;
&lt;h2&gt;Enter Unity&lt;/h2&gt;
&lt;p&gt;After dropping the windows native plugin into Unity, which is running in the windows VM, I selected the plugin to play around with the plugin inspector. The plugin inspector is &lt;strong&gt;super&lt;/strong&gt;, and I&amp;rsquo;m really thankful the Unity people had put it there&amp;hellip;&lt;/p&gt;
&lt;p&gt;I noticed that the settings for the plugin should be set to &amp;ldquo;Standalone - Windows x86_64&amp;rdquo; as well as the &amp;ldquo;Editor - Windows x86_64&amp;rdquo;. with these two options set, the game was running like a charm on the windows installation of Unity.&lt;/p&gt;
&lt;p&gt;That was the end of it, really. I checked in the changes, and it&amp;rsquo;s time for the developer to take over from here.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I cannot explain how many days of this everlasting project have been drained on this freaking C game logic. To run it on the server, I had to figure out how to compile it on linux, and played around with CMake. In order to develop and test it properly on OS X, I had to prepare an Xcode project and Swift tests. Then, there is this post, where I had to run a windows VM and compile a DLL. But that&amp;rsquo;s not all&amp;hellip;&lt;/p&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been running game bots on my machine that automatically login to the server and play games against each other. After leaving the bots running for a few hours, I noticed my computer was getting quite slow&amp;hellip; Yup, it was a memory leak, and the only possible culprit was the C library. The other languages in the stack (Elixir, Python) are garbage collected language, that don&amp;rsquo;t leak memory.... Also&amp;hellip;&lt;/p&gt;
&lt;p&gt;In order to connect the logic to the server, I had to use python and distutils to wrap the C code with a sane python script that Elixir can interact with. On the Unity game side, I needed to play around a lot with Swig and building the library for all sorts of target platforms&amp;hellip;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;QUITE A FREAKING ORDEAL!&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="posts"></category><category term="programming"></category></entry><entry><title>Elixir Exits</title><link href="https://mazyod.com/blog/2016/06/15/elixir-exits/" rel="alternate"></link><published>2016-06-15T21:22:24+00:00</published><updated>2016-06-15T21:22:24+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-15:/blog/2016/06/15/elixir-exits/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;While working with Elixir and building a dope server, I came across an annoying error resulting from an &amp;ldquo;exit&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Exits in Elixir are propagated in processes similar to how errors and exceptions do in your other familiar languages. When a process exits abnormally, the &amp;ldquo;exit&amp;rdquo; hits the linked nodes …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;While working with Elixir and building a dope server, I came across an annoying error resulting from an &amp;ldquo;exit&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Exits in Elixir are propagated in processes similar to how errors and exceptions do in your other familiar languages. When a process exits abnormally, the &amp;ldquo;exit&amp;rdquo; hits the linked nodes, possibly crashing them if they don&amp;rsquo;t handle the exit properly.&lt;/p&gt;
&lt;p&gt;I won&amp;rsquo;t be covering exits in details, since there is already a great resource that explains this concepts really well &lt;a href="https://elixirschool.com/lessons/advanced/error-handling/#exiting"&gt;over here&lt;/a&gt;. What I will be covering is one painful place where an exit can kill your app!&lt;/p&gt;
&lt;h2&gt;Taming GenServers&lt;/h2&gt;
&lt;p&gt;While running integration tests on my server, I noticed an annoying occasional error that kept occurring from time to time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;** (EXIT from #PID&amp;lt;0.276.0&amp;gt;) exited in: GenServer.call(#PID&amp;lt;0.279.0&amp;gt;, :msg, 5000)
    ** (EXIT) no process
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hrm .. that&amp;rsquo;s a pretty obvious error. We are attempting to do a &lt;code&gt;GenServer.call&lt;/code&gt;, but the process we are calling into is not available. Looking at my code, and indeed. Sometimes I receive a late incoming message after the &amp;ldquo;Game Process&amp;rdquo; has been terminated, causing this error to be thrown.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Simple enough!&amp;rdquo;, I thought to myself. &amp;ldquo;I&amp;rsquo;ll just check if the process is available before I perform any calls!&amp;rdquo;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alive?&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perform_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Hmm &amp;hellip; On second thought, that won&amp;rsquo;t do it. Care to spot the error in the code above?&lt;/p&gt;
&lt;p&gt;Indeed, Elixir is a highly concurrent language, and if the process happens to exit after the &lt;code&gt;Process.alive?&lt;/code&gt; check is evaluated, we will end up crashing nevertheless!! We need to improve this somehow &amp;hellip; How about being optimistic?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# optimistically run the code expecting it to succeed&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nc"&gt;Server&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perform_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# if it fails, we&amp;#39;ll just absorb the error&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="ss"&gt;:exit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="bp"&gt;_&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Looks good, doesn&amp;rsquo;t it? Well, kind of. The code above does work as advertised, and it may make sense in many situations, but it doesn&amp;rsquo;t make the most sense in my situation. You see, when you run into these issues in Elixir, the first solution you should think of is &amp;ldquo;how can I better refactor my code to avoid this error completely?&amp;rdquo;. Is that possible? YES!&lt;/p&gt;
&lt;h2&gt;Ideal Solution&lt;/h2&gt;
&lt;p&gt;After conceiving the previous error handling solution, I launched atom and started writing unit tests that reproduce the failing situation. After I wrote the tests, I ran then, and &amp;hellip; they didn&amp;rsquo;t fail! WAT?!&lt;/p&gt;
&lt;p&gt;Looking at the code, I am pretty sure I am triggering a &lt;code&gt;GenServer&lt;/code&gt; call after the &lt;code&gt;GenServer&lt;/code&gt; process has died .. But no exits are raised this time?&lt;/p&gt;
&lt;p&gt;After looking closer at the code, I was actually testing against one of the methods that performed a &lt;code&gt;GenServer&lt;/code&gt; &lt;em&gt;cast&lt;/em&gt; rather than a &lt;em&gt;call&lt;/em&gt;. Since performing a call is suppose to return a reply, the &lt;code&gt;GenServer&lt;/code&gt; throws an error, since no reply is gonna be given back! But if we do a &lt;code&gt;cast&lt;/code&gt;, there is no reply anyway, so the message fails silently&amp;hellip;&lt;/p&gt;
&lt;p&gt;Once I realized this neat property of &lt;code&gt;call&lt;/code&gt; vs &lt;code&gt;cast&lt;/code&gt;, I simply realized that the best solution is to decouple my phoenix channel process from the game state process, by always perform casts instead of calls. If there is a result to be sent back to the client, the game state will just push the event from within.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Even though time is super scarce these days to be writing blog posts, these types of stories and encounters are the reason I have this blog in the first place, so indeed .. It would be foolish to skip on this.&lt;/p&gt;
&lt;p&gt;The quality of the post is admittedly bad and vague at best, but it hopefully delivers at least once useful lesson:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Always be casting!&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="posts"></category><category term="elixir"></category></entry><entry><title>Sysadmin</title><link href="https://mazyod.com/blog/2016/06/14/sysadmin/" rel="alternate"></link><published>2016-06-14T05:21:00+00:00</published><updated>2016-06-14T05:21:00+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-14:/blog/2016/06/14/sysadmin/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d be committing treason not showing this xkcd comic in a sysadmin related article:&lt;/p&gt;
&lt;p&gt;&lt;img alt="xkcd" src="/images/devotion_to_duty.png"&gt;&lt;/p&gt;
&lt;p&gt;With that taken care of, what is this post about exactly? Well, recently I had to wear the sysadmin hat. Here is what wiki has to say about sysadmin:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A system administrator, or sysadmin …&lt;/p&gt;&lt;/blockquote&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d be committing treason not showing this xkcd comic in a sysadmin related article:&lt;/p&gt;
&lt;p&gt;&lt;img alt="xkcd" src="/images/devotion_to_duty.png"&gt;&lt;/p&gt;
&lt;p&gt;With that taken care of, what is this post about exactly? Well, recently I had to wear the sysadmin hat. Here is what wiki has to say about sysadmin:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A system administrator, or sysadmin, is a person who is responsible for the upkeep, configuration, and reliable operation of computer systems; especially multi-user computers, such as servers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Close enough.&lt;/p&gt;
&lt;p&gt;The reason I had to do sysadmin stuff is that I needed to deploy the Elixir game server for the remote team to use. They breezed through the simple tasks and features, and are ready to integrate the networking stuff.&lt;/p&gt;
&lt;p&gt;Traditionally, I had a lot of issues with server deployment. Issues were related to DBs, web server setup, logging, and server monitoring. Thankfully, this time around, all these issues were taken care of! Let&amp;rsquo;s see how&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Database&lt;/h2&gt;
&lt;p&gt;I decided to use Postgres as a DB, mostly because it&amp;rsquo;s the recommended DB for Phoenix. The only issue is, it&amp;rsquo;s not the most usable DB on the planet. You can get into a lot of quirks and configuration issues while setting it up yourself, so that&amp;rsquo;s why I decided to just avoid that from the get go.&lt;/p&gt;
&lt;p&gt;A quick google search for recommended database services near my servers (hosted on DigitalOcean) showed me &lt;a href="https://www.databaselabs.io/"&gt;DatabaseLabs&lt;/a&gt;. The reason I felt comfortable going with them is because they only provide the thing that I needed, and nothing else. Postgres hosting on DigitalOcean. Period.&lt;/p&gt;
&lt;p&gt;I had a lot of minor issues with the service, in the beginning. The dashboard was kinda crappy, DataGrip didn&amp;rsquo;t work, and I wasn&amp;rsquo;t able to navigate and make use of simple resources due to bad UX.&lt;/p&gt;
&lt;p&gt;Thankfully, they had a kickass support team. I was able to communicate with them and voice my concerned, which they acknowledged and addressed fairly quickly. So, it&amp;rsquo;s definitely a :thumbs_up: from me!&lt;/p&gt;
&lt;p&gt;&lt;img alt="databaselabs dashboard" src="/images/databaselabs.png"&gt;&lt;/p&gt;
&lt;h2&gt;Web Server&lt;/h2&gt;
&lt;p&gt;My previous server was using Apache, and it was a hellish experience to say the least. Too much crap to configure, too much intricacy involved in the way you structure your directories! There is no IDE or magic wand you can just wave here, so things didn&amp;rsquo;t go well.&lt;/p&gt;
&lt;p&gt;Last time, I decided to use a Flask web service, and it is almost unthinkable to use the default web server shipping with Flask, hence I resorted to Apache.&lt;/p&gt;
&lt;p&gt;This time around, I am using Elixir! Built with Erlang! Which has the superb Cowboy webserver! Yup, I decided not to bother with nginx nor Apache this time around, and just expose the Cowboy server to the outside world. It&amp;rsquo;s great, and I&amp;rsquo;m not complaining for now.&lt;/p&gt;
&lt;p&gt;So, the way to solve the web server issue is to eliminate the need to have a web server in the first place! OK, I understand that at some point I may need to install a web server in order to do proxying and load balancing, but for now .. Wheeee!&lt;/p&gt;
&lt;p&gt;&lt;img alt="cowboy logo" src="/images/cowboy-home.png"&gt;&lt;/p&gt;
&lt;h2&gt;Logging&lt;/h2&gt;
&lt;p&gt;Ah &amp;hellip; Logging &amp;hellip; Such an under-appreciated corner of the backend world. Up until now, working with over 5 different companies with relatively sophisticated servers didn&amp;rsquo;t have proper logging aggregation. When I would ask for logs to look at, they all pointed me to a bunch of zip files dumped on the server &amp;hellip; Really?&lt;/p&gt;
&lt;p&gt;The thing is, that&amp;rsquo;s what most servers come by default with. A file logger with log rotation support. This means, the server writes the logs to a file, and once a duration or files size limit is reached, the log file is compressed, moved elsewhere, and a new file is created. This is cool, but how are we suppose to go through all these logs!&lt;/p&gt;
&lt;p&gt;Enter the logging aggregator.&lt;/p&gt;
&lt;p&gt;With a logging aggregator, you can send all these logs to a centralized location, and this service would basically provide you with powerful search and lookup tools to properly look through all these logs.&lt;/p&gt;
&lt;p&gt;The service I came across and found extremely useful was &lt;a href="https://papertrailapp.com"&gt;papertrail&lt;/a&gt;. It had everything I could ask for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Regex search and filtration&lt;/li&gt;
&lt;li&gt;Generous free trail&lt;/li&gt;
&lt;li&gt;Elixir logger library&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With papertrail, I can finally run my phoenix server in detached mode without worrying about losing any logs, since they are all sent to papertrail where I can see them update live!&lt;/p&gt;
&lt;p&gt;&lt;img alt="papertrail sample" src="/images/papertrail.png"&gt;&lt;/p&gt;
&lt;p&gt;A few honorable mentions include &lt;a href="https://logdna.com"&gt;logDNA&lt;/a&gt; and &lt;a href="https://logentries.com"&gt;logentries&lt;/a&gt;. They look super promising as well, but I am simply too satisfied with papertrail to bother with exploring alternatives.&lt;/p&gt;
&lt;h2&gt;Monitoring&lt;/h2&gt;
&lt;p&gt;We reach our final point, monitoring. During the EC2 days, I had setup New Relic, which was a terrible experience. After adding their library into my server code, it didn&amp;rsquo;t really perform well, and I could&amp;rsquo;ve sworn my server performance was degraded. In either case, I really hated the fact that I had to change my server code just to get simple monitoring.&lt;/p&gt;
&lt;p&gt;AWS so called &amp;ldquo;Cloud Watch&amp;rdquo; is the absolute worst. I&amp;rsquo;ve also tried several solutions for monitoring any ubuntu instances, and they were all annoying to deal with &amp;hellip; Monitoring was another thing I didn&amp;rsquo;t get right in the past.&lt;/p&gt;
&lt;p&gt;This time around, again, there it was. The best monitoring service I could ask for, &lt;a href="https://www.datadoghq.com/"&gt;DataDog&lt;/a&gt;. Just be deploying a small script, I now have a daemon up an running on my server, sending all the relevant stats the the data dog server, for me to view conveniently from their dashboard.&lt;/p&gt;
&lt;p&gt;Data dog&amp;rsquo;s great features include a fully customizable dashboard, where you choose the stats you wanna monitor, generous free tier (again), and slick UI, integration, and many other neat features. I am really happy with it.&lt;/p&gt;
&lt;p&gt;&lt;img alt="datadog dashboard" src="/images/datadog.png"&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I didn&amp;rsquo;t need to use Docker this time around, nor am I bothering with fancy continuous integration nor deployment&amp;hellip; It&amp;rsquo;s time to get just the bare minimum done and ship. I&amp;rsquo;ve actually been preaching this a lot to people around me making the same grave mistake over and over again &amp;hellip;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;We must perfect this!&amp;rdquo;, &amp;ldquo;It&amp;rsquo;s all about the technology!&amp;rdquo;, &amp;ldquo;We want the best code EVAR!!&amp;rdquo; &amp;hellip; No.&lt;/p&gt;
&lt;p&gt;The whole idea of startups that deliver consumer products is to MITIGATE the risk of technologies and focus on delivering the best user experience possible. Stop bogging down on the details of the technology stack, and focus on delivery, shipment and customer satisfaction. This is mostly due to endless iterations on the product facing side, not the tech side....&lt;/p&gt;
&lt;p&gt;HEED MY WORDS!&lt;/p&gt;</content><category term="posts"></category><category term="backend"></category></entry><entry><title>GenServer</title><link href="https://mazyod.com/blog/2016/06/08/genserver/" rel="alternate"></link><published>2016-06-08T17:42:57+00:00</published><updated>2016-06-08T17:42:57+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-08:/blog/2016/06/08/genserver/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the previous post, I didn&amp;rsquo;t have enough space nor time to cover GenServers in Elixir. This is a follow up to cover just that. Before actually talking about GenServers, let&amp;rsquo;s discuss the design pattern behind it, namely, the Actor model.&lt;/p&gt;
&lt;h2&gt;Cameras, Light, Action!&lt;/h2&gt;
&lt;p&gt;The actor model …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In the previous post, I didn&amp;rsquo;t have enough space nor time to cover GenServers in Elixir. This is a follow up to cover just that. Before actually talking about GenServers, let&amp;rsquo;s discuss the design pattern behind it, namely, the Actor model.&lt;/p&gt;
&lt;h2&gt;Cameras, Light, Action!&lt;/h2&gt;
&lt;p&gt;The actor model is an architectural design pattern that dictates how you structure your code. The basic building block in this design pattern is the &amp;ldquo;actor&amp;rdquo;, hence comes the name. So, what is an actor?&lt;/p&gt;
&lt;p&gt;An actor is a self-contained entity that has it&amp;rsquo;s own model and logic. You can think of an actor as a small application running within your application! It is self-contained, so no one can access the actor&amp;rsquo;s memory directly. In order to do useful things with actors, we use message passing to facilitate data flow and perform useful tasks.&lt;/p&gt;
&lt;p&gt;In languages such as C++ and Swift, we usually see actors running in their own threads. This is perfect for concurrent applications, since you can then make use of as much CPU cores as you have. However, threads are not light-weight and can get rather computationally expensive.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why in Elixir, we have Erlang VM processes, which are super-light weight processes that provide us with the same features as OS processes, but can be created within a few µs.&lt;/p&gt;
&lt;p&gt;Enough with the theoretical talks, and let&amp;rsquo;s talk using some real examples.&lt;/p&gt;
&lt;h3&gt;A Game Server&lt;/h3&gt;
&lt;p&gt;Since I&amp;rsquo;m building a game server with Elixir, I&amp;rsquo;ll derive the example directly from how I built the backend.&lt;/p&gt;
&lt;p&gt;First off, I define some global actors that are always needed and provide useful, persistent functionality to the rest of the application. Some of these actors include:&lt;/p&gt;
&lt;h4&gt;The Referee&lt;/h4&gt;
&lt;p&gt;The referee is an actor that accepts a &lt;code&gt;Game&lt;/code&gt; object for further processing. That&amp;rsquo;s it! So, for example, whenever a game ends on the server, we send the associated &lt;code&gt;Game&lt;/code&gt; object to the referee, and move on. The referee looks at the &lt;code&gt;Game&lt;/code&gt; object, and updates the players rating, stats, and rewards.&lt;/p&gt;
&lt;h3&gt;The Matchmaker&lt;/h3&gt;
&lt;p&gt;Another interesting actor is the Matchmaker. It has a runloop that triggers every 5 seconds to process the players in the matchmaking queue, and matches them together so they can start playing a game. You send it the player data along with the &amp;ldquo;channel pid&amp;rdquo;, and once it finds a match, it will respond to the &amp;ldquo;channel pid&amp;rdquo; with the result.&lt;/p&gt;
&lt;p&gt;You don&amp;rsquo;t have to worry about what &amp;ldquo;channel pid&amp;rdquo; is, but for the curious, it is like the &amp;ldquo;address&amp;rdquo; of the player actor. So, we use the address to communicate the result back to the player.&lt;/p&gt;
&lt;h2&gt;GenServer&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;GenServer&lt;/code&gt; stands for Generic Server. It&amp;rsquo;s basically a server that you can spawn at runtime to server you various functionality. It is immune to race conditions and can do it&amp;rsquo;s work synchronously and asynchronously, based on the function definition (as we will see in a sec). With these features in mind, it makes it the basic building block for creating actors in Elixir. &lt;/p&gt;
&lt;p&gt;To get comfortable with GenServers, spend some time writing various GenServers, have them talk to one another, add them to the Elixir application supervision tree, and you should be golden.&lt;/p&gt;
&lt;p&gt;Again, for illustration purposes, let&amp;rsquo;s see an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# enable this module as a genserver&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;GenServer&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# this is the entry point to spawn a server&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# just keep in mind :ok is passed to the init function below&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# here, we define the &amp;quot;API&amp;quot; of the server&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:increment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;# now, we proceed with the server implementation&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# 0 is the state of the server&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# the first &amp;quot;state&amp;quot; we pass in, is the return value&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;# the second &amp;quot;state&amp;quot; is the state of the server, which remains unchanged&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:increment&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That looks intimidating, even to me now, since I&amp;rsquo;ve been using ExActor for a while &amp;hellip; But, you really need to learn the basics before moving on. Just keep in mind that it get better. Once you learn GenServers the hard way, you can start utilizing ExActor to take care of the boilerplate crap.&lt;/p&gt;
&lt;p&gt;Before breaking this down and understanding it, let&amp;rsquo;s run it!&lt;/p&gt;
&lt;h3&gt;Execution&lt;/h3&gt;
&lt;p&gt;Simply, create a &lt;code&gt;counter.ex&lt;/code&gt; file somewhere, and paste in the code above as is. Then, navigate to that file&amp;rsquo;s directory in terminal, and launch &lt;code&gt;iex&lt;/code&gt;. Once &lt;code&gt;iex&lt;/code&gt; is launched, execute &lt;code&gt;c("counter.ex")&lt;/code&gt;. This should load the &lt;code&gt;MyApp.Counter&lt;/code&gt; module into &lt;code&gt;iex&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can then test the counter like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;counter.ex&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;
&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;         &lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;#PID&amp;lt;0.67.0&amp;gt;}&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;increment&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="ss"&gt;:ok&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yay, so it works! Let&amp;rsquo;s take a close look as to why it works.&lt;/p&gt;
&lt;h3&gt;Start&lt;/h3&gt;
&lt;p&gt;To define an entry point for spawning a server, we have to define a &lt;code&gt;start&lt;/code&gt; or &lt;code&gt;start_link&lt;/code&gt; method. The difference is irrelevant now. The function simply calls into &lt;code&gt;GenServer&lt;/code&gt; module to spawn and initialize a new process running our &lt;code&gt;Counter&lt;/code&gt; server. The parameters we pass in are for initializing the server, but since this server is so simple, there is nothing to initialize.&lt;/p&gt;
&lt;p&gt;The start function returns a tuple &lt;code&gt;{:ok, pid}&lt;/code&gt;, which we can pattern match against in order to extract the pid, which is the server address. We need it in order to perform the operations.&lt;/p&gt;
&lt;h3&gt;Init&lt;/h3&gt;
&lt;p&gt;Init is where you&amp;rsquo;d want to initialize your server state and prepare any data or timers. Once you&amp;rsquo;re ready, you simply return &lt;code&gt;{:ok, state}&lt;/code&gt; at the end. &lt;code&gt;:ok&lt;/code&gt; indicates initialization was successful, and &lt;code&gt;state&lt;/code&gt; is any arbitrary data you want the server to hold. In our case, the server&amp;rsquo;s state is just a number.&lt;/p&gt;
&lt;h3&gt;Cast vs Call&lt;/h3&gt;
&lt;p&gt;After that, we start defining the server API. What functionality do we want the server to provide? In this case, we want a way to increment the number of the server, and request that number sometime in the future.&lt;/p&gt;
&lt;p&gt;We would like to implement the increment function asynchronously, so we don&amp;rsquo;t block the caller as the server state is updated. We do that by calling &lt;code&gt;GenServer.cast&lt;/code&gt; in the API methods. This means, if we have a long running operation running after the call is made, the process performing the call will not block and wait for a response, it will simply move on.&lt;/p&gt;
&lt;p&gt;However, if we want to implement retrieving the counter value, the caller process must block and wait for the response from the server with the counter value. We can instruct the caller to do that by using &lt;code&gt;GenServer.call&lt;/code&gt;. After calling into the Counter server for the counter value, we use &lt;code&gt;{:reply, state, state}&lt;/code&gt; to return the counter value.&lt;/p&gt;
&lt;p&gt;The first &lt;code&gt;state&lt;/code&gt; is just the return value to the caller. The second &lt;code&gt;state&lt;/code&gt; means we want to maintain the current state of the server without changing anything. So, if for any reason we want to clear the counter after it has been read, we can do:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handle_call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:reply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, note the function signature of the &lt;code&gt;handle_call&lt;/code&gt; and &lt;code&gt;handle_cast&lt;/code&gt; methods, and how they are different. The &lt;code&gt;handle_call&lt;/code&gt; takes one more extra parameter, which is &lt;code&gt;from&lt;/code&gt;. &lt;code&gt;from&lt;/code&gt; is the pid of the caller! Since it is blocking and waiting for a response, you may not have a result yet, so you want to &amp;ldquo;reply later&amp;rdquo;. This will allow you to reply whenever you want.&lt;/p&gt;
&lt;h2&gt;ExActor&lt;/h2&gt;
&lt;p&gt;After looking at the previous example, let&amp;rsquo;s look at how we can use the &lt;code&gt;ExActor&lt;/code&gt; library to really simplify how we implement actors and GenServers in Elixir.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Counter&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kn"&gt;use&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;ExActor&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;initial_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;defcall&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;defcast&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;incr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;new_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I know, this is absurdly OP!! We no longer have to define API methods and handler methods. We no longer have to worry about the function signatures nor the syntax of how we reply at the end of the function. This is objectively awesome and simple, and enhances readability A LOT.&lt;/p&gt;
&lt;p&gt;The reason you should use vanilla &lt;code&gt;GenServer&lt;/code&gt; before jumping on &lt;code&gt;ExActor&lt;/code&gt; is because of ambiguity that &lt;code&gt;ExActor&lt;/code&gt; introduces. For example, in &lt;code&gt;ExActor&lt;/code&gt; there is no &lt;code&gt;pid&lt;/code&gt; parameter passed into &lt;code&gt;count&lt;/code&gt; and &lt;code&gt;increment&lt;/code&gt; functions, even though we still need to pass in the pid of the server. This is taken care of by the library, but one may be confused by such details if they didn&amp;rsquo;t try using vanilla &lt;code&gt;GenServer&lt;/code&gt; first.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The journey to master GenServers doesn&amp;rsquo;t end here. I&amp;rsquo;ve missed out a lot of details because of time constraints. Details include passing in a name for the server, message handling using &lt;code&gt;handle_info&lt;/code&gt; and other tips and tricks to make the most out of this extremely useful toy.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t get intimidated, tho. Once you&amp;rsquo;ve mastered &lt;code&gt;GenServer&lt;/code&gt;, IMHO, you are good to go to use Elixir in your own projects.&lt;/p&gt;</content><category term="posts"></category><category term="elixir"></category></entry><entry><title>Elixir Tutorial</title><link href="https://mazyod.com/blog/2016/06/05/elixir-tutorial/" rel="alternate"></link><published>2016-06-05T21:30:37+00:00</published><updated>2016-06-05T21:30:37+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-05:/blog/2016/06/05/elixir-tutorial/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is so nice&amp;hellip; I&amp;rsquo;ve recently updated my sublime text theme, and the markdown plugin rendering is looking gorgeous.&lt;/p&gt;
&lt;p&gt;Ehm, anyways. So, Jim has more ideas to share, and they still keep me up at night. I am not sure what this says about my personality, but usually …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is so nice&amp;hellip; I&amp;rsquo;ve recently updated my sublime text theme, and the markdown plugin rendering is looking gorgeous.&lt;/p&gt;
&lt;p&gt;Ehm, anyways. So, Jim has more ideas to share, and they still keep me up at night. I am not sure what this says about my personality, but usually I find other people&amp;rsquo;s ideas much more fascinating than mine.&lt;/p&gt;
&lt;p&gt;So, the idea was to write Elixir tutorials (or a single tutorial, I don&amp;rsquo;t remember). I initially dismissed the idea, since I really didn&amp;rsquo;t go through any useful tutorial at all. Most of my learning was through Elixir talks with practical demos, and by reading source code on github!! But! Just sharing that experience would be a tutorial in itself, so here it goes.&lt;/p&gt;
&lt;h2&gt;Elixir?&lt;/h2&gt;
&lt;p&gt;Oh, yes. What is Elixir? Elixir is a concurrent, functional programming language built on top of Erlang. It brings you all the Erlang goodness that has been developed since 1986, with a clean and nice syntax that is actually usable and easy to work with.&lt;/p&gt;
&lt;p&gt;Elixir excels at building highly scalable, fault-tolerant backend systems. Definitely use it to replace your background workers, Redis, RabbitMQ and other services, since Elixir is enough to do all that. As for web services, you can take a look at Phoenix, however, it wouldn&amp;rsquo;t make much sense writing a web app in Phoenix, when Node and Rails exist for that purpose.&lt;/p&gt;
&lt;h2&gt;Start Being Functional&lt;/h2&gt;
&lt;p&gt;I really believe people without object-oriented programming background are the people most suited to learning elixir. This is mainly because Elixir is a functional programing language.&lt;/p&gt;
&lt;p&gt;Functional programming is simple and straight forward. The reason most developers I met found it difficult was because they were retrofitting object oriented concepts into this pristine language, which is a Very Bad Idea™.&lt;/p&gt;
&lt;p&gt;So, even though I believe that, I am unfortunately burdened with an object-oriented mind while I was learning Elixir. So I have to present this post from the perspective of such persona.&lt;/p&gt;
&lt;p&gt;OK, so before we proceed, I am presenting what really helped me get a hang of Elixir as a competent, object-oriented programmer with absolutely no prior experience with functional programming, so here it goes.&lt;/p&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;First of, you need to get your hands dirty with the absolute basics. Don&amp;rsquo;t even worry nor think about OTP, aynsc tasks, and all that exciting goodness. Just focus on the absolute basics, namely:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pattern Matching&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Pattern matching is everywhere in Elixir, and comes from Erlang. You must get this out of the way as soon as possible. While you learn pattern matching, you&amp;rsquo;ll also see the different data types in Elixir, hopefully.&lt;/p&gt;
&lt;p&gt;For the sake of example, let&amp;rsquo;s put a few code snippets to illustrate:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# string pattern matching&lt;/span&gt;
&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;I am string&amp;quot;&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;I am &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;suffix&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;
&lt;span class="c1"&gt;# suffix is a variable containing &amp;quot;string&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;# tuple pattern matching&lt;/span&gt;
&lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;string&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;tuple&lt;/span&gt;
&lt;span class="c1"&gt;# num is a variable containing 123&lt;/span&gt;

&lt;span class="c1"&gt;# list pattern matching&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# head contains 1, and tail contains [2, 3, 4, 5]&lt;/span&gt;

&lt;span class="c1"&gt;# map pattern matching&lt;/span&gt;
&lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# x contains 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A few remarks on the code illustrated above:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;By providing the actual value, such as &lt;code&gt;"string"&lt;/code&gt;, or &lt;code&gt;"x"&lt;/code&gt;, that value is checked against by the pattern matching engine for conformance. If a mismatch occurs on a value, an error is raised.&lt;/li&gt;
&lt;li&gt;On the other hand, providing a variable name, such as &lt;code&gt;head&lt;/code&gt; or &lt;code&gt;suffix&lt;/code&gt;, this will &lt;strong&gt;capture&lt;/strong&gt; the matching part into the variable for further processing.&lt;/li&gt;
&lt;li&gt;Finally, notice that pattern matching on maps is special. Usually, when you pattern match, you have to pattern match against the whole thing. The whole list, or the whole string for example. But for maps, we are ignoring the extra keys we don&amp;rsquo;t care about, and the pattern matching succeeds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Modules &amp;amp; Functions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;There is no such things as classes, so we have modules instead. A module is a collection of functions, almost like a namespace, but has other uses. There is not much to cover here, really. You just define a module, write some functions within, and you&amp;rsquo;re done.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;defmodule&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Calculator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="kd"&gt;def&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# somewhere else&lt;/span&gt;
&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;MyApp.Calculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# result contains 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;This should be straight-forward, really. If you come from a language that uses braces or something, just replace them with &lt;code&gt;do ... end&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Most languages also have &lt;code&gt;return&lt;/code&gt; keyword, but in elixir, everything is an expression. You don&amp;rsquo;t need to worry about what that means, but just keep in mind that the last statement in the function will automatically be returned.&lt;/li&gt;
&lt;li&gt;There are no objects, no constructors, no destructors. It&amp;rsquo;s just so simple.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Standard Library&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The Elixir standard library is quite neat with most of the functionality you&amp;rsquo;d probably need already built in. You got the usual suspects, like &lt;code&gt;IO&lt;/code&gt;, &lt;code&gt;Enum&lt;/code&gt;, &lt;code&gt;File&lt;/code&gt;, and such. You also have the data types, like &lt;code&gt;String&lt;/code&gt;, &lt;code&gt;List&lt;/code&gt;, &lt;code&gt;Map&lt;/code&gt;, and such.&lt;/p&gt;
&lt;p&gt;My best friend when it comes to exploring and learning the standard library is &lt;a href="https://kapeli.com/dash"&gt;Dash&lt;/a&gt;. &lt;a href="http://devdocs.io/"&gt;DevDocs&lt;/a&gt; is a free and open source alternative, but isn&amp;rsquo;t being updated as frequently. It suffers from the relatively high maintenance overhead.&lt;/p&gt;
&lt;p&gt;Armed with those tools, you should be good to go. Don&amp;rsquo;t spend too much time goofing around with the tools, once you start building your application, you should be able to pick it up easily without impeding momentum.&lt;/p&gt;
&lt;h2&gt;GenServer&lt;/h2&gt;
&lt;p&gt;This is the last piece of the puzzle. Now, in order to actually build useful applications with Elixir, you really need to master GenServers. They are simple and easy to work with, but may be daunting to the uninitiated.&lt;/p&gt;
&lt;p&gt;&amp;hellip; After spending about 30 minutes writing about GenServers, I realized it&amp;rsquo;s just too big of a topic to cover here! So, fret not. I simply moved the content I write to a new draft that I will hopefully cover next. For now, spend some time on the topics already covered!!&lt;/p&gt;
&lt;h2&gt;Remarks&lt;/h2&gt;
&lt;p&gt;OK, I lied. There are some missing pieces you should learn and be wary of. Most importantly is message passing. Sending messages between processes is a super important feature to learn and understand properly if you plan on building anything useful with Elixir. &lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s quite a broad topic, but the basics should be simple enough to grasp on your own. I am out of time for now, so maybe it&amp;rsquo;s worth exploring in its own article one day.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The more Elixir developers out there, the better. If you ever fall in love with it, spread the word! Also, join the &lt;a href="https://elixir-lang.slack.com"&gt;elixir slack channel&lt;/a&gt;, where the core team hangs out. Most importantly, don&amp;rsquo;t give up on Elixir except after attempting to build a full app with it. If that leaves a bad taste in your mouth, then you&amp;rsquo;re allowed to look at alternatives!&lt;/p&gt;</content><category term="posts"></category><category term="elixir"></category></entry><entry><title>Phoenix Channel with a User</title><link href="https://mazyod.com/blog/2016/06/04/phoenix-channel-with-a-user/" rel="alternate"></link><published>2016-06-04T00:47:29+00:00</published><updated>2016-06-04T00:47:29+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-04:/blog/2016/06/04/phoenix-channel-with-a-user/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.phoenixframework.org/"&gt;Phoenix&lt;/a&gt; is a productive web framework written in Elixir. It excels in many things, but nothing nearly as amazing as realtime websockets.&lt;/p&gt;
&lt;p&gt;Phoenix provides an abstraction over soft-realtime communication called &amp;ldquo;Channels&amp;rdquo;. This basically handles structuring realtime communication for you. The way this structure works is out-of-scope for the moment …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.phoenixframework.org/"&gt;Phoenix&lt;/a&gt; is a productive web framework written in Elixir. It excels in many things, but nothing nearly as amazing as realtime websockets.&lt;/p&gt;
&lt;p&gt;Phoenix provides an abstraction over soft-realtime communication called &amp;ldquo;Channels&amp;rdquo;. This basically handles structuring realtime communication for you. The way this structure works is out-of-scope for the moment, so please read on it from the Phoenix docs. It is really close to the Socket.IO model.&lt;/p&gt;
&lt;p&gt;Onto the actual post!&lt;/p&gt;
&lt;h2&gt;Say My Name&lt;/h2&gt;
&lt;p&gt;So, assuming you know what Phoenix channels are by now, let&amp;rsquo;s look at an interesting problem you might easily find yourself handling: User data.&lt;/p&gt;
&lt;p&gt;Assuming you only allow authenticated users to have access to your websocket connection (hint: good idea), you will need connecting clients to send some sort of credentials. Using these credentials, you can authenticate the user, and move on.&lt;/p&gt;
&lt;p&gt;Since usually we would want to perform user-related actions throughout the span of the client&amp;rsquo;s connection, this means we should associate the socket connection with that particular user somehow for later reference. Easily enough, we read the docs inlined in our &lt;code&gt;user_socket.ex&lt;/code&gt; file and find:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;verified_user_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nice! We can assign arbitrary data to our socket, and it will be accessible on all our channels through &lt;code&gt;socket.assigns&lt;/code&gt;! .. Not so fast. What should we actually store there? &lt;code&gt;user_id&lt;/code&gt;? The whole &lt;code&gt;User&lt;/code&gt; object? Something else?&lt;/p&gt;
&lt;h3&gt;User Object&lt;/h3&gt;
&lt;p&gt;For my use case, I rely heavily on the user data, like the username and rating, so I decided to just assign the whole User object to the socket and move on. This served me quite well during the development process, and didn&amp;rsquo;t cause any issues.. Until I reached the part of the implementation where I need to process and update user data.&lt;/p&gt;
&lt;p&gt;You see, Elixir is a functional programming language, so everything is passed by value. The User object we assigned to the socket is no exception. With that in mind, it means I can&amp;rsquo;t easily update all User objects being passed around the socket and channels easily.&lt;/p&gt;
&lt;p&gt;Moreover, I was tempted in several places to update the user data on the DB using the &lt;code&gt;User&lt;/code&gt; object I had .. But it could be outdated! That looked really dangerous, and had to be eliminated altogether.&lt;/p&gt;
&lt;h3&gt;User Id&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s just follow the guide and use &lt;code&gt;user_id&lt;/code&gt;? NO. This will result in the need to make synchronous DB calls, which will render the whole reason we are using realtime websockets useless. It would also make the code unbearable.&lt;/p&gt;
&lt;p&gt;This could work for other use cases where the user data isn&amp;rsquo;t needed directly in the channels, but rather used in workers or background services. In that case, passing &lt;code&gt;user_id&lt;/code&gt; around would be your best options.&lt;/p&gt;
&lt;h3&gt;Global&lt;/h3&gt;
&lt;p&gt;The first solution I tried was so stupid, lol. I created a &lt;code&gt;GenServer&lt;/code&gt; to hold the &lt;code&gt;User&lt;/code&gt; object, and called it &lt;code&gt;UserService&lt;/code&gt;. This process is registered globally, and hence can be accessed from anywhere! This would eliminate the update issues as well as the performance concerns. In fact, this service would perform updates quickly on its own state, then dispatch an async DB task. Sounds great!&lt;/p&gt;
&lt;p&gt;The issue really became glaring once I started running the tests. Unless I create a new user for every single test, I&amp;rsquo;ll have to properly clean up any running user process once each test is over&amp;hellip; This is because after the first test runs and registers the user process globally, the second test then attempts to register the user process again, resulting in an error.&lt;/p&gt;
&lt;p&gt;There are way to circumvent this particular issue, but that wouldn&amp;rsquo;t overcomplicate the software at hand, making future me a sad panda. Instead, I took a step back and decided to simplify the solution.&lt;/p&gt;
&lt;h3&gt;Ephemeral&lt;/h3&gt;
&lt;p&gt;Of course! First, instead of passing the process around and dealing with such an obscure data type, I decided to pass a &lt;code&gt;Player&lt;/code&gt; object. &lt;code&gt;Player&lt;/code&gt; is a struct with a subset of the &lt;code&gt;User&lt;/code&gt; data, namely just the &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;rating&lt;/code&gt;. I figured out that this is all I need, really! By moving to this new type, I am also safe from updating the actual &lt;code&gt;User&lt;/code&gt; object using outdated info, since I can&amp;rsquo;t simply use the &lt;code&gt;Player&lt;/code&gt; object to update the user, I need the &lt;code&gt;User&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;Then! In the places where I was actually performing the user updates, I simply spawned a new &lt;code&gt;UserService&lt;/code&gt; process! With the new process, I perform all the updates I need, then simply wait for the process to expire and perish. No global state involved, still performant as hell, and encapsulated within &lt;code&gt;UserService&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s quickly skim over the final architecture we reached:&lt;/p&gt;
&lt;p&gt;Once the client connects using a token, we authenticate the user, while fetching her data. We take a subset of that data and assign it to the socket.&lt;/p&gt;
&lt;p&gt;As the user connects to channels and starts interacting with the server, we use this subset to perform the basic operations we need. Once we need to actually update the user&amp;rsquo;s data, we spawn a &lt;code&gt;UserService&lt;/code&gt; process, which has the available operations implemented. We perform the operations we need, and leave it to expire and die, cleaning up itself.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s it .. The fact that I can easily explain such a sophisticated topic with such simple terms is really a testament to the platform itself.&lt;/p&gt;
&lt;p&gt;Elixir. Phoenix. Thank you.&lt;/p&gt;</content><category term="posts"></category><category term="phoenix"></category></entry><entry><title>Backend Testing Using Bots</title><link href="https://mazyod.com/blog/2016/06/01/backend-testing-using-bots/" rel="alternate"></link><published>2016-06-01T10:59:31+00:00</published><updated>2016-06-01T10:59:31+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-06-01:/blog/2016/06/01/backend-testing-using-bots/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;With the rise of chat bots, concurrent programming, and elixir, I thought I might as well shed some light on the elixir bots server I wrote for my own needs.&lt;/p&gt;
&lt;p&gt;The reason I wrote a bots server was mainly because I found it difficult to test my game&amp;rsquo;s …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;With the rise of chat bots, concurrent programming, and elixir, I thought I might as well shed some light on the elixir bots server I wrote for my own needs.&lt;/p&gt;
&lt;p&gt;The reason I wrote a bots server was mainly because I found it difficult to test my game&amp;rsquo;s online capabilities on my own. When I go the game rooms, there are no rooms, since there are no players yet! Also, not enough online events are being triggered, such as leaderboard changes and what not..&lt;/p&gt;
&lt;p&gt;So, in order to test my game client, as well as provide a rough integration testing mechanism, I decided to write this bot server.&lt;/p&gt;
&lt;h2&gt;I Am Bot&lt;/h2&gt;
&lt;p&gt;The bot server is a simple Elixir application that has 20 bots sitting directly in the main supervision tree. Using a &lt;code&gt;one_to_one&lt;/code&gt; strategy, the bots will recover after a crash, and life goes on.&lt;/p&gt;
&lt;p&gt;A bot process is basically this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="fc" src="/images/bot-fc.png"&gt;&lt;/p&gt;
&lt;p&gt;Just an infinite loop that updates the GUI with the latest state and messages, and another loop that triggers the &amp;ldquo;interact&amp;rdquo; action. The really interesting part is the interaction, so let&amp;rsquo;s take a closer look at that.&lt;/p&gt;
&lt;h3&gt;Machine With Finite States&lt;/h3&gt;
&lt;p&gt;I am using the neat &lt;a href="https://github.com/sasa1977/fsm"&gt;FSM&lt;/a&gt; library to create an FSM that the &amp;ldquo;bot state&amp;rdquo; uses to manage the logic. The &amp;ldquo;bot state&amp;rdquo; is just an FSM stored in the bot process, and works something like this:&lt;/p&gt;
&lt;p&gt;&lt;img alt="fsm" src="/images/bot-fsm.png"&gt;&lt;/p&gt;
&lt;p&gt;So, after connecting to the server, whenever we send the FSM an &amp;ldquo;interact&amp;rdquo; event, it simply runs some logic to figure out what the next state should be. The available options are also weighted in such a way that we control the chances of the bot choosing one path over the other. This is extremely important, since for example, once the bot enters matchmaking, we give it a 5% chance to give up and leave the matchmaking queue. This is to ensure we test all possible actions!&lt;/p&gt;
&lt;p&gt;If we were to look at some of the fsm code, it looks something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;### MATCHMAKING&lt;/span&gt;

&lt;span class="n"&gt;defstate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;matchmaking&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;## Interact&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;defevent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;interact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duplicate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:wait&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:leave&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;case&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="ss"&gt;:wait&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nc"&gt;GUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:gui&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Matchmaking ...&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nc"&gt;WS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;send_heartbeat&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;next_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:matchmaking&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="ss"&gt;:leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nc"&gt;GUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:gui&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;sick of mm waiting!&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nc"&gt;WS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;next_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:connected&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:channel&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="c1"&gt;## Opponent found&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;defevent&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;on_reply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;do&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;GUI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update_message&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;:gui&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;[&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;]: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;WS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;leave&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;matchmaking:&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nc"&gt;WS&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%{}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;next_state&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:mm_session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code above represents the &amp;ldquo;matchmaking&amp;rdquo; state. So, the bot has entered a matchmaking queue, and is waiting for an opponent. While waiting, each time we call &amp;ldquo;interact&amp;rdquo;, we either continue waiting, or give up and leave. Chances are 24:1 as you can see above.&lt;/p&gt;
&lt;p&gt;As for the &lt;code&gt;defevent&lt;/code&gt;, this simply handles the server message if an opponent is found. The way this works is, the bot process simply forwards all incoming server messages to the bot state using the &lt;code&gt;on_reply&lt;/code&gt; event. We use pattern matching to extract the id of the matchmaking session, then move on the &lt;code&gt;mm_session&lt;/code&gt; state!&lt;/p&gt;
&lt;h3&gt;Closing Remarks&lt;/h3&gt;
&lt;p&gt;That&amp;rsquo;s all there is to it, really. I have to say, this server was more than worth writing. It helped my test the client app easily, as well as find bugs and issues on the server side.&lt;/p&gt;
&lt;p&gt;For example, I run 20 bots at once and they all play and interact on the game server. After integrating the game logic on the server, I found that the game logic process hangs in certain rare cases! I would have never caught that by testing manually on a Unity client. Also, the game logic is a python process, so when it hangs, it really breaks the whole server! That&amp;rsquo;s terrible, but thankfully, resolved.&lt;/p&gt;
&lt;p&gt;Also, I can easily do load testing by running 1000 bots or so on one machine and closely monitor the server&amp;rsquo;s performance. I am not worried about performance at all in this case, since it&amp;rsquo;s a turn-based game, but it&amp;rsquo;s easy to do, so I&amp;rsquo;d probably do it just for the heck of it.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Elixir is just great for writing bots, whether they are chat bots, testing sentinels, or whatever. The Actor-based model maps to bots 1-to-1, so that should really be a surprise!&lt;/p&gt;</content><category term="elixir"></category><category term="elixir"></category><category term="bot"></category><category term="programming"></category><category term="backend"></category><category term="erlang"></category><category term="fsm"></category><category term="state"></category><category term="machine"></category><category term="ai"></category><category term="artificial"></category><category term="intelligence"></category><category term="supervisor"></category></entry><entry><title>Structuring Firebase Data</title><link href="https://mazyod.com/blog/2016/05/31/structuring-firebase-data/" rel="alternate"></link><published>2016-05-31T12:17:32+00:00</published><updated>2016-05-31T12:17:32+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-31:/blog/2016/05/31/structuring-firebase-data/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This isn&amp;rsquo;t the first Firebase post, however, it is the first since the recent revamp Google introduced to Firebase. It has a neat new logo, website, and features! It&amp;rsquo;s no longer just a datastore, but includes analytics, crash reporting, push notifications, and tons of other features.&lt;/p&gt;
&lt;p&gt;Recently …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This isn&amp;rsquo;t the first Firebase post, however, it is the first since the recent revamp Google introduced to Firebase. It has a neat new logo, website, and features! It&amp;rsquo;s no longer just a datastore, but includes analytics, crash reporting, push notifications, and tons of other features.&lt;/p&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve worked with Firebase again for a client, and this time, it was about consuming data, not generating it. This presented an interesting challenge, how should the data be structured?&lt;/p&gt;
&lt;h2&gt;Basics&lt;/h2&gt;
&lt;p&gt;There are a few select rules you should bear in mind while designing your data, and they will allow you to achieve maximum efficiency while working with Firebase.&lt;/p&gt;
&lt;h3&gt;UI Driven&lt;/h3&gt;
&lt;p&gt;This is really counter-intuitive to DBAs. Usually, data is structured using ER diagrams or whatnot, and modeled in a DB regardless of how the UI is gonna present it. Not the case with Firebase.&lt;/p&gt;
&lt;p&gt;Since Firebase is &lt;strong&gt;directly&lt;/strong&gt; consumed on the client side, the data should be designed around the UI. Doing this will give you realtime super-powers and maximum flexibility in managing your apps data.&lt;/p&gt;
&lt;p&gt;The not-so-bad downside is, you&amp;rsquo;re gonna have to replicate your datastore everytime you make a breaking change to the datastore schema, in order to not break existing clients. Not too bad.&lt;/p&gt;
&lt;h3&gt;Flat vs Nested&lt;/h3&gt;
&lt;p&gt;One simple rule:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Nest static data. Flatten dynamic data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The real challenge here is identifying what is static data and what&amp;rsquo;s dynamic data.&lt;/p&gt;
&lt;p&gt;Basically, if you have a nested type which once you instantiate, you really don&amp;rsquo;t want to get updates on that object anymore, that&amp;rsquo;s static data. A good example of this is the menu of an e-Commerce application. You simply create the whole menu hierarchy once, and load it. We don&amp;rsquo;t really care if a new category is added, we can reload the next time the app launches.&lt;/p&gt;
&lt;p&gt;Dynamic data, on the other hand, is data that can change after being loaded the first time. I would go as far as saying, it&amp;rsquo;s any data that you attach a Firebase observer to. This data should be flat, for the sake of reducing the updates overhead, as well as keeping your client code clean and segregated. Let&amp;rsquo;s expand on this a little with an example.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ve got a user&amp;rsquo;s feed of stories, and each story has comments. So, if you decide to use a nested structure where you have:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Root/users/USER/feed/[STORY]/[COMMENT]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anytime a comment is added to that last array, the &lt;strong&gt;whole&lt;/strong&gt; object gets rewritten, all the way from the /users path, which can get insanely expensive pretty quickly. The alternative, is to denormalize your data, and just include object ids, which you later fetch using another Firebase instance:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Root/users/[USER_ID]&lt;/li&gt;
&lt;li&gt;Root/[USER_ID]/user_data&lt;/li&gt;
&lt;li&gt;Root/[USER_STORIES]/[STORY]&lt;/li&gt;
&lt;li&gt;Root/[STORY_COMMENTS]/[COMMENT]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;By moving everything to the root, it may seem like a chore at first, but this isolation is quite neat, as it allows you to fetch and update data in an isolated way.&lt;/p&gt;
&lt;p&gt;The drawback this time is, what if we want to inform the user object of an update, when a new comment is added? Using nesting, the whole tree will get rewritten, and hence causing the whole tree to get an update notification.&lt;/p&gt;
&lt;p&gt;The only reasonable way I know of is to wire things together on the client side. So, once a new comment is added, for example, you would update the UI to add that comment. As you do that, the user-related UI would be fetching the comment count from deep within the tree.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s gonna be really painful if Firebase meets the same fate as StackMob and Parse, but for rapid development, you really don&amp;rsquo;t have much of a choice but use these services&amp;hellip;&lt;/p&gt;</content><category term="posts"></category><category term="firebase"></category></entry><entry><title>Be Animate!</title><link href="https://mazyod.com/blog/2016/05/29/be-animate/" rel="alternate"></link><published>2016-05-29T11:04:13+00:00</published><updated>2016-05-29T11:04:13+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-29:/blog/2016/05/29/be-animate/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Apparently, the word &amp;ldquo;animate&amp;rdquo; can be an adjective to &amp;ldquo;being alive or having life&amp;rdquo;. Well, that could apply to animate and inanimate objects alike &amp;hellip; This is getting confusing.&lt;/p&gt;
&lt;p&gt;Well, the point is, this will be a quick post about an animation prototyping tool called &amp;ldquo;Origami&amp;rdquo;. I&amp;rsquo;ve been using …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Apparently, the word &amp;ldquo;animate&amp;rdquo; can be an adjective to &amp;ldquo;being alive or having life&amp;rdquo;. Well, that could apply to animate and inanimate objects alike &amp;hellip; This is getting confusing.&lt;/p&gt;
&lt;p&gt;Well, the point is, this will be a quick post about an animation prototyping tool called &amp;ldquo;Origami&amp;rdquo;. I&amp;rsquo;ve been using it recently to test how an animation looks before the developer goes through the trouble of implementing it.&lt;/p&gt;
&lt;h2&gt;Japanese Paper Models?&lt;/h2&gt;
&lt;p&gt;Well, yeah, originally at least. That&amp;rsquo;s what the word origami initially means, however, the name was also used by facebook as the name for their animation tool, as well.&lt;/p&gt;
&lt;p&gt;So, yeah, Facebook decided to build a free animation prototyping tool, and against all odds and expectations, the tool is actually just a bunch of &amp;ldquo;patches&amp;rdquo; on top of Quartz Composer!&lt;/p&gt;
&lt;p&gt;Quartz Composer is an app which is part of Apple&amp;rsquo;s developer tools, and it is almost as old as time itself. I don&amp;rsquo;t recall it getting much recognition by the Apple developer communities, I guess mainly because it&amp;rsquo;s a designer tool that requires technical expertise&amp;hellip;&lt;/p&gt;
&lt;p&gt;So, yeah, to wrap it up, if you are a developer who excels at designing animations and looking for a tool to quickly prototype your animation ideas, you fit nicely within Origami&amp;rsquo;s target audience.&lt;/p&gt;
&lt;h2&gt;How Good Exactly?&lt;/h2&gt;
&lt;p&gt;Origami is so good, to the point that I was able to prototype two relatively complex interactions and animations within than an hour .. while on a plane (as they say in Japanese &amp;ldquo;Sasuga, Digital Nomad-san!&amp;rdquo;). Granted, I spent a few hours a few days ago playing around with the workflow and getting my hands dirty with the nuts and bolts of this tool.&lt;/p&gt;
&lt;p&gt;In any case, the main reason Origami either shines or diminishes in a team is because of its unique workflow. Until now, every single animation system I&amp;rsquo;ve ever worked with uses keyframes (Flash, AE, Unity, Spine, &amp;hellip; etc). That makes sense (kinda), but makes things hard and complicated once you start introducing interactions. Most people put up with it, tho, since everyone is familiar with keyframes.&lt;/p&gt;
&lt;p&gt;Quartz Composer, however, allows you to create processing units, called &amp;ldquo;patches&amp;rdquo;. Each patch has inputs and outputs, and you basically compose your whole setup using these units. That&amp;rsquo;s it. The basic idea is so simple and elegant, you just have to fall in love with it .. Kinda reminds me of Elixir, actually, since its basically just a collection of units of work, as well. Except in Elixir, they are called &amp;ldquo;Processes&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The final note I want to shed some light on today is maintainability. Thanks to the availability of groups and other patches that allow you to breakdown your system into smaller pieces, it really allows you to build complicated hierarchies without losing your mind.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve tried Pixate studio, by Google, and saw other alternatives, but they were expensive (such as AE). So, I was kinda forced to try out Origami at first, but the short tutorials at their website was more than enough to convince me to test it out and ultimately use it as the primary animation tool.&lt;/p&gt;</content><category term="posts"></category><category term="origami"></category></entry><entry><title>Unity + JSON</title><link href="https://mazyod.com/blog/2016/05/26/unity-json/" rel="alternate"></link><published>2016-05-26T22:56:47+00:00</published><updated>2016-05-26T22:56:47+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-26:/blog/2016/05/26/unity-json/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;JSON is such a trivial matter to be discussed .. but for whatever reason, it&amp;rsquo;s quite a chore on Unity.&lt;/p&gt;
&lt;h2&gt;Newton?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Newtonsoft.Json&lt;/code&gt;, also known as &lt;code&gt;JSON.Net&lt;/code&gt;, is the defacto JSON serialization in C#. It&amp;rsquo;s superb, with great features, like automatic object serialization/deserialization, which reduces tons …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;JSON is such a trivial matter to be discussed .. but for whatever reason, it&amp;rsquo;s quite a chore on Unity.&lt;/p&gt;
&lt;h2&gt;Newton?&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Newtonsoft.Json&lt;/code&gt;, also known as &lt;code&gt;JSON.Net&lt;/code&gt;, is the defacto JSON serialization in C#. It&amp;rsquo;s superb, with great features, like automatic object serialization/deserialization, which reduces tons of boilerplate code.&lt;/p&gt;
&lt;p&gt;Unfortunately, it&amp;rsquo;s not stable on Unity. It&amp;rsquo;s crazy, but it&amp;rsquo;s true. As far as I can tell, it only crashes on IL2Cpp, and does so due to some unimplemented reflection feature of some sort .. So, we can&amp;rsquo;t use this for serious Unity + iOS development!&lt;/p&gt;
&lt;h2&gt;JsonUtility?&lt;/h2&gt;
&lt;p&gt;This ships with Unity, and guarantees the least footprint + garbage, which makes it super fast and efficient for games. Unfortunately, as with most thing in Unity, it&amp;rsquo;s poorly documented making it almost useless.&lt;/p&gt;
&lt;p&gt;Another issue is that it doesn&amp;rsquo;t have a &amp;ldquo;JSON object&amp;rdquo; class that can dynamically construct a JSON object. For example, Newtonsoft has &lt;code&gt;JObject&lt;/code&gt;, which you can instantiate and use like a dictionary.&lt;/p&gt;
&lt;h2&gt;AssetStore?&lt;/h2&gt;
&lt;p&gt;Yeah, that&amp;rsquo;s our final hope &amp;hellip; Tons of options are available, but since I am using a vendored library that uses the Newtonsoft namespace and &lt;code&gt;JObject&lt;/code&gt; functionality extensively, hence I&amp;rsquo;ve decided to get a drop-in replacement.&lt;/p&gt;
&lt;p&gt;The best option I found was &lt;a href="http://www.parentelement.com/assets/json_net_unity"&gt;this&lt;/a&gt;. A highly rated, well received drop-in replacement, open-sourced replacement to the broken Newtonsoft. $25 means 30 minutes of my development service, definitely worthwhile.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Unity is still lacking, but it has made insane leaps thanks to IL2Cpp, 2D support, UI system, and the great community. Please do consider it as an alternative to whatever else you&amp;rsquo;re using. (&lt;em&gt;cough&lt;/em&gt; SpriteKit &lt;em&gt;cough&lt;/em&gt; Cocos2d)&lt;/p&gt;</content><category term="posts"></category><category term="unity"></category></entry><entry><title>Unity on iOS</title><link href="https://mazyod.com/blog/2016/05/26/unity-on-ios/" rel="alternate"></link><published>2016-05-26T19:08:35+00:00</published><updated>2016-05-26T19:08:35+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-26:/blog/2016/05/26/unity-on-ios/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;So, over the past three days, I spent two sleepless nights, and kept on working with one goal in mind .. Get the game working on iOS.&lt;/p&gt;
&lt;p&gt;Wait, this is Unity! The game engine that promises painless cross-platform compatibility! Why do I have to spend over three days to make …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;So, over the past three days, I spent two sleepless nights, and kept on working with one goal in mind .. Get the game working on iOS.&lt;/p&gt;
&lt;p&gt;Wait, this is Unity! The game engine that promises painless cross-platform compatibility! Why do I have to spend over three days to make the game work properly on iOS? Especially, given the game was developed for OS X, and works great there. I mean, not too far off, you know?&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s see why Unity fails us here&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Enter the Walled Garden of Apples&lt;/h2&gt;
&lt;p&gt;The main issue is that Apple&amp;rsquo;s platform is &amp;ldquo;too closed&amp;rdquo;. You can&amp;rsquo;t dynamically link libraries. You can dynamically load scripts. You can&amp;rsquo;t scratch your ear without Apple&amp;rsquo;s written consent .... ARGH.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not letting Unity off the hook easily, tho. They knew about this, and should work around it without exposing those issues to the end-developer. Granted, that&amp;rsquo;s (much) easier said than done.&lt;/p&gt;
&lt;p&gt;Here are some specific details about the issues&amp;hellip;&lt;/p&gt;
&lt;h3&gt;Native Code&lt;/h3&gt;
&lt;p&gt;The main issue I was wrestling was making my native library work on iOS. Sure, if you only wanted to compile the native functions and have them accessible from Unity, all you do is drop the &lt;code&gt;*.c&lt;/code&gt; files into the Plugins/iOS folder. However, my library is complex, and even has C# wrappers generated with swig, so&amp;hellip; It&amp;rsquo;s gonna be a battle.&lt;/p&gt;
&lt;h5&gt;Mono2x&lt;/h5&gt;
&lt;p&gt;First issue was related to Mono &lt;code&gt;dllimport&lt;/code&gt;&amp;rsquo;s &lt;code&gt;EntryPoint&lt;/code&gt;. You see, when you generate C# wrappers with swig, it also generates a C wrapper that wraps all your methods within &lt;code&gt;CSharp_xxx&lt;/code&gt; calls (for whatever reason). So, the C# wrappers are actually functions with the original C function names, but the entry point is set to the &lt;code&gt;CSharp_xxx&lt;/code&gt; variant.... So?&lt;/p&gt;
&lt;p&gt;Plain and simple, this breaks when compiling for iOS with Mono 2x scripting backend. The generated Xcode project and code simply fail to locate the original function symbols, when it should be looking for the &lt;code&gt;CSharp_xxx&lt;/code&gt; variants &amp;hellip; This is confusing, see the example below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// CSharp&lt;/span&gt;
&lt;span class="na"&gt;[dllimport(&amp;quot;MyLib&amp;quot;, EntryPoint=&amp;quot;CSharp_NativeMethod&amp;quot;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NativeMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hope it&amp;rsquo;s clear now .. Unity generates an Xcode project that calls &lt;code&gt;NativeMethod&lt;/code&gt; for some reason, when it should honor the &lt;code&gt;EntryPoint&lt;/code&gt; argument and call that name instead&amp;hellip; That easily cost me tons of headache.&lt;/p&gt;
&lt;p&gt;So, I tackled this issue with my trusted friend, Python. By integrating a python script after the swig generation script, I was able to transform the generated swig methods (as seen above) to the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// CSharp&lt;/span&gt;
&lt;span class="na"&gt;[dllimport(&amp;quot;MyLib&amp;quot;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CSharp_NativeMethod&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;NativeMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;CSharp_NativeMethod&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;I basically got rid of the useless &lt;code&gt;EntryPoint&lt;/code&gt; argument, renamed the extern method to match the swig wrapper, and finally created an alias for the other C# scripts, for compatibility. Let&amp;rsquo;s run and see &amp;hellip; Boom! Crashes and burns.&lt;/p&gt;
&lt;p&gt;Looking closer at the errors, seems that they are related to the callbacks swig registers to the native code. Basically, there is C# code that swig generates to pass managed (C#) methods to the native code, in order for the native code to callback the C# code in case of an exception, for example.&lt;/p&gt;
&lt;p&gt;Yay .... it finally works! &amp;hellip; oh, wait.&lt;/p&gt;
&lt;p&gt;So, I ran the game on iOS, and indeed it worked for a bit, but quickly crashed because of &lt;code&gt;System.Linq&lt;/code&gt; calls .. Apparently, Mono2x doesn&amp;rsquo;t properly implement all &lt;code&gt;System.Linq&lt;/code&gt; functionality. Since I am in love with functional programming, I really leveraged those methods everywhere! Is all hope lost? No .. It seems if I just switch to IL2Cpp, this would resolve the issue&amp;hellip; Let&amp;rsquo;s try that.&lt;/p&gt;
&lt;h4&gt;IL2Cpp&lt;/h4&gt;
&lt;p&gt;So, according to some resources I found online, it seems that switching the scripting backend to IL2Cpp seems to be the way Unity is moving, and is the best future proof solution. Also, it has better performance and compatibility (especially with iOS), and most importantly, it should resolve the &lt;code&gt;System.Linq&lt;/code&gt; issues! Time to flip that switch, and hope for the best&amp;hellip;&lt;/p&gt;
&lt;p&gt;Boom! The native code I just fixed broke .. AGAIN. Well, at least it broke in a good way &lt;code&gt;( ͡° ͜ʖ ͡°)&lt;/code&gt;. What does that even mean?&lt;/p&gt;
&lt;p&gt;Well, it means the hacks I previously implemented are breaking the code! I need just remove them .. probably. So, I&amp;rsquo;ve deleted the previous python script that removes the callbacks and hacks the method names, and the result &amp;hellip; Ye-arr&amp;hellip; Not quite.&lt;/p&gt;
&lt;p&gt;I got an error from the callbacks that says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Please use &amp;ldquo;MonoPInvokeCallback&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;hrm&amp;hellip; Ok. So, back to the python script.. Let&amp;rsquo;s hack this one, shouldn&amp;rsquo;t be too hard, and it wasn&amp;rsquo;t. I simply iterated over the callback methods being passed to the native code, and added the following decorator:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;[MonoPInvokeCallback(typeof(DELEGATE))]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Instead of &lt;code&gt;DELEGATE&lt;/code&gt;, I have the actual delegate definition that matches the callback signature &amp;hellip; Let&amp;rsquo;s run it, one more time&amp;hellip; Success! IL2Cpp banzai! It was unfortunate that I wasted time on the previous fix, but wasn&amp;rsquo;t too bad.&lt;/p&gt;
&lt;h3&gt;Being a Perfectionist&lt;/h3&gt;
&lt;p&gt;Because I unfortunately always strive for perfection, I was like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What if I can build the Swig C# code into mono DLLs, then conditionally compile them to each platform using the plugin inspector?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img alt="cat" src="/images/cat-tie.jpg"&gt;&lt;/p&gt;
&lt;p&gt;After much time ~~wasted~~ invested into learning how to build and package mono code on OS X, it just failed horribly. Managed libraries can&amp;rsquo;t contain unmanaged code calls, it seems, so that had to be thrown out the window.&lt;/p&gt;
&lt;p&gt;So, I went back to my old friend, again, and asked him to do me a solid. While processing the PInvoke C# file with all the decorators and such, I add some more python code to do the following:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;callback_decorator_template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;{indentation}&lt;/span&gt;&lt;span class="s2"&gt;#if UNITY_IOS&lt;/span&gt;
&lt;span class="si"&gt;{indentation}{ios_decorator}&lt;/span&gt;
&lt;span class="si"&gt;{indentation}&lt;/span&gt;&lt;span class="s2"&gt;#else&lt;/span&gt;
&lt;span class="si"&gt;{indentation}{original_decrorator}&lt;/span&gt;
&lt;span class="si"&gt;{indentation}&lt;/span&gt;&lt;span class="s2"&gt;#endif&lt;/span&gt;
&lt;span class="s2"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Basically, another regex processor that replaces the default native calls decorators and adds this conditional compilation directive based on the platform. This way, we can maintain iOS and OS X support!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Yeah, quite a hearty post, with lots of issues and stuff .. Even though, I&amp;rsquo;ve yet to cover all the details! For example, the Xcode build process, the swig integration, the &lt;code&gt;mcs&lt;/code&gt; tool to build the mono libraries, Unity&amp;rsquo;s plugin inspector, &amp;hellip; and so on.&lt;/p&gt;
&lt;p&gt;Well, at least the general idea is out there, hopefully the small details are easy to figure out! (yeah, that&amp;rsquo;s rarely the case).&lt;/p&gt;</content><category term="posts"></category><category term="unity"></category></entry><entry><title>A Game Dev Tale</title><link href="https://mazyod.com/blog/2016/05/23/a-game-dev-tale/" rel="alternate"></link><published>2016-05-23T22:44:06+00:00</published><updated>2016-05-23T22:44:06+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-23:/blog/2016/05/23/a-game-dev-tale/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The main reason I sit on the computer these days and write code is mostly to ship a game .. A game that has become a serious stigma I can no longer ignore.&lt;/p&gt;
&lt;p&gt;There are so many tales and angles to this journey, I cannot hope to cover it all …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;The main reason I sit on the computer these days and write code is mostly to ship a game .. A game that has become a serious stigma I can no longer ignore.&lt;/p&gt;
&lt;p&gt;There are so many tales and angles to this journey, I cannot hope to cover it all in one post.. In fact, I started this post to write about integrating C with Elixir, and the introduction ended up being so long, to the point that it warranted a post in itself! So, let&amp;rsquo;s leave the C and Elixir part, and take a look at how the development the game&amp;rsquo;s backend underwent.&lt;/p&gt;
&lt;p&gt;So.. Come a bit closer and hear, for there are some lessons for the programmer folk.&lt;/p&gt;
&lt;h2&gt;Seeking the Truth&lt;/h2&gt;
&lt;p&gt;So, during my insane 4-year game development journey, one of my main sources of distress was the Game Logic. Since the beginning, I&amp;rsquo;ve decided to use C for performance and portability. I &lt;strong&gt;really&lt;/strong&gt; need C performance, and maybe even parallelism if this game makes it. Then there is portability, which is for the sake of running the code on the client and server&amp;hellip; Here is where things get hairy.&lt;/p&gt;
&lt;h3&gt;The Fox&lt;/h3&gt;
&lt;p&gt;The first server I wanted to use was SmartFoxServer or Photon server (mid 2013), but they had &amp;ldquo;lacking&amp;rdquo; capabilities, or so I thought. SmartFox didn&amp;rsquo;t have great C++ client library support, and Photon didn&amp;rsquo;t allow for custom game logic to run in the cloud (urgh, I didn&amp;rsquo;t even need that back then). &lt;/p&gt;
&lt;p&gt;When I say the client library was bad, I mean it took me around a week to just compile it. It wasn&amp;rsquo;t just me, people all over the SmartFoxServer forums were confused with all the issues the library had. Once it compiled, yeah, it crashed, and was no longer a feasible approach..&lt;/p&gt;
&lt;p&gt;That made me go all custom backend, and start writing a game server using GAE and python.&lt;/p&gt;
&lt;h3&gt;The Snake&lt;/h3&gt;
&lt;p&gt;The Python road was kinda documented on this blog a bit (late 2013 - mid 2014), and it was an utter disaster. For whatever reason, I thought I was doing things right, by incrementally building features, without a clear overview nor goal of the final backend&amp;hellip;&lt;/p&gt;
&lt;p&gt;To give you a glimpse of the issues, we can separate the issues into different groups, based on the source of the issue:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;GAE&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;GAE was a promising platform back in 2013, but severely lacking. Getting SSL calls to work locally, you had to hack the GAE code. To run sockets, you had to add a payment method, which they promise they won&amp;rsquo;t deduct from, but they eventually do. And of course, to run background jobs on GAE, you could only schedule 1-minute interval cron jobs &amp;hellip; How limiting.&lt;/p&gt;
&lt;p&gt;Testing GAE was horrible. Period. You gotta setup a testbed, do some various crap, just to be able to test a limited part of the code &amp;hellip; Damn&amp;hellip; I ended up writing functional tests rather than unit tests, which as we all know, aren&amp;rsquo;t viable for quickly catching bugs during development.&lt;/p&gt;
&lt;p&gt;An important problem that I completely ignored here was the game logic. I had no way to run C code on GAE, so I was gonna depend on the client code being 100%, which will &lt;strong&gt;never&lt;/strong&gt; go well .. Yeah &amp;hellip;&lt;/p&gt;
&lt;p&gt;Now, after gaining some experience about backends, I could&amp;rsquo;ve solved the background jobs as well as the C library stuff using RPC. GAE has great RPC support, but oh well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;REST&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;REST APIs are horrible for games. I don&amp;rsquo;t care about all the hacky workarounds that people have built around REST to make it work for games, it is just horrible&amp;hellip; Every small feature I wanted to implement on top of REST took tons of hours of design and implementation. Think about how to solve game rooms, matchmaking and game sessions using REST apis, it&amp;rsquo;s really awkward.&lt;/p&gt;
&lt;p&gt;The best way I learned to make REST work was to wrap everything in timers. So, the backend has an &amp;ldquo;inactivity timer&amp;rdquo; to determine if a client is still connected. The client has a &amp;ldquo;heartbeat&amp;rdquo; timer to poll the backend for results, as well as inform the backend that it is alive .. Yuck &amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Webapp2&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The default web service framework shipping with GAE back then, and to put it simply, it ain&amp;rsquo;t Django. It was severely lacking, resources were scarce, and for a frontend developer like me jumping to backend development through this .. It was just a bad idea.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;That sounds really appealing to most developers, but is just a another painful obstacle between you and shipping your crap. The seamless scalability GAE offers is at the expense of various restrictions, really hurtful at time, with of course, the added overhead of learning new design patterns to do simple stuff.&lt;/p&gt;
&lt;p&gt;Thanks to scalability, the recommended approach I came across was to use secure cookies. This makes your backend stateless, and the client maintains the state with each request .. Countless headaches were there. Then comes the shared backend state, which is just inevitable in games. You had to use the memcache thingie, and writing models and using it was also yet another pain.&lt;/p&gt;
&lt;p&gt;All that to say, it wasn&amp;rsquo;t a good idea to go head first into a new technology like GAE back then, without clearly knowing what I was after.. Yeah, sounds obvious, but &amp;hellip; oh well.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Moving On&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Yeah, that fell flat on it&amp;rsquo;s face&amp;hellip; So, let&amp;rsquo;s write C++!&lt;/p&gt;
&lt;h3&gt;The Goliath&lt;/h3&gt;
&lt;p&gt;So, at some point, I decided to go full-fledged custom C++ (mid 2014 - mid 2015). At the same time, I looked at the UI designs I&amp;rsquo;ve had made about a year ago, and decided they are no good. I was gonna work my ass off on this C++ code base, the game better be worthwhile! So, it was time to overhaul the whole thing, design and development.&lt;/p&gt;
&lt;p&gt;As for the code part, so much time was spent designing and implementing C++ code, on both the client and backend. The main reason I considered C++ was my discovery of the Poco libraries.&lt;/p&gt;
&lt;p&gt;Poco is a really neat set of open-source C++ libraries. Browsing their code, I had faith that people &lt;strong&gt;can&lt;/strong&gt; write sane C++ code, without losing their mind. So, following their lead, and using most of their libraries, I was able to write a &amp;ldquo;working&amp;rdquo; game frontend and backend in like .. 6 months.&lt;/p&gt;
&lt;p&gt;Now, &amp;ldquo;working&amp;rdquo; doesn&amp;rsquo;t mean complete .. Actually, it was extremely far from complete. Even though it wasn&amp;rsquo;t a horrible experience, it was ideal for a one-person team. Juggling the frontend and backend code bases in C++ was extremely painful, I needed help, and I needed it fast.&lt;/p&gt;
&lt;p&gt;So, during my stay in SF, late 2015, I interviewed a seasoned C++ developer, actually a core Poco contributor. He was great, and I after setting everything up, preparing the tasks, and putting together a plan &amp;hellip; It struck me.&lt;/p&gt;
&lt;p&gt;I was in a hostile-type place, with 2 other developers.. One of them recently graduated from a code bootcamp, and he and his mates already had a working platform with some pretty neat functionality. That really dragged me back into reality&amp;hellip; Why not? What&amp;rsquo;s so special about them? They used node! In conjunction with Socket.IO! &amp;hellip; URGH!&lt;/p&gt;
&lt;p&gt;I quickly scrambled to see how easy it was, and I had a working, realtime server within the hour, just how cool is that? .. Yeah, I had to call that C++ developer and tell him not to show up for work (remotely). I really feel bad for backing off like that, but it had to be done .. I needed a sane technology like node, and to end this C++ madness.&lt;/p&gt;
&lt;h3&gt;The Elixir of Immortality&lt;/h3&gt;
&lt;p&gt;Yeah, by late 2015, it was time for me to just take a deep breath, sit back and really weigh out my options here ..&lt;/p&gt;
&lt;p&gt;Node was an extremely viable option, but I simply hate JS (pre-ES6). I desperately looking around the web for solutions.. People seem to like Ruby, so I gave that a go. Nope, won&amp;rsquo;t work for me. It had so much of the crap I hated about python and GAE, in the sense that you do a lot of documentation reading and configuring rather than writing your business logic. At that point, it was gonna be Node&amp;hellip;&lt;/p&gt;
&lt;p&gt;God bless &lt;a href="http://surajms.com"&gt;this man&lt;/a&gt;, for he has planted the Elixir seed in my head. He is a Ruby developer by trade, but was fed up with Ruby, and wanted to try something new. He mentioned Elixir in the past, and it clicked with me while I was there .. Yeah, why not give that a try?&lt;/p&gt;
&lt;p&gt;Thanks to all the amazing content online that talk about Elixir, and using it for game development even, I was able to come to peace that .. Yes. This is the technology most befitting for this project.&lt;/p&gt;
&lt;h2&gt;What Now?&lt;/h2&gt;
&lt;p&gt;No, I haven&amp;rsquo;t shipped yet, lol. However, For the first time in the history of this game, the backend is way ahead of the frontend. In fact, there was only one way I realized I can ever ship, and that is by using Unity and hiring a developer to do everything, lol.&lt;/p&gt;
&lt;p&gt;Unity is great, it&amp;rsquo;s a kitchen sink that just gives you everything you need to ship a great game, with the expense of forcing you to do things its way. I was able to get some good results on my own in Unity, but nothing close to what a veteran was able to do within a single day.&lt;/p&gt;
&lt;p&gt;Yeah, today marked the first day working with a freelancing studio, and their progress was nothing short of staggering. Looking at their pipeline, I could see reused scripts, custom Unity editor controls, and tons of other important details they built during their 5-year experience with Unity. They went all in, and it is definitely paying off.&lt;/p&gt;
&lt;p&gt;What now? Time to trust these guys with the Unity side, and do my best to support them where I can while implementing final touches on the backend! If this work out, that would mean the first 3.5 years where nothing but a learning journey, while the final 6 months were the actual work that made it into the game .. Since the backend, frontend, and design were all remade! (except the C game logic, lol. That is the only piece of legacy that survived this harsh journey).&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I am not even trying to obscure the root cause of this delay in the game development process. The root cause for the game taking 4 years up till now is most definitely due to my lack of experience and focus. All the technologies I mentioned work great for their purposes, but when you decide to go with something, don&amp;rsquo;t hear the preaches.. Just cast it on your requirements.&lt;/p&gt;</content><category term="posts"></category><category term="game-development"></category></entry><entry><title>See Sharp</title><link href="https://mazyod.com/blog/2016/05/22/see-sharp/" rel="alternate"></link><published>2016-05-22T18:26:04+00:00</published><updated>2016-05-22T18:26:04+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-22:/blog/2016/05/22/see-sharp/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In order to see sharp, we eat carrots! Unfortunately tho, that&amp;rsquo;s now how we C#. C# is a language brought to us by Microsoft in an attempt to beat Java (I think?). Since the dark ages, I misconceived C# as a Java close that didn&amp;rsquo;t really bring …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In order to see sharp, we eat carrots! Unfortunately tho, that&amp;rsquo;s now how we C#. C# is a language brought to us by Microsoft in an attempt to beat Java (I think?). Since the dark ages, I misconceived C# as a Java close that didn&amp;rsquo;t really bring anything new to the table &amp;hellip; I&amp;rsquo;m severely mistaken.&lt;/p&gt;
&lt;p&gt;I guess the main reason I am writing this is because our old friend &lt;a href="http://jimmaru.wordpress.com/"&gt;Jim&lt;/a&gt; kept telling me how he wrote setters and getters in C# the &amp;ldquo;Java way&amp;rdquo;, by defining the set &amp;amp; get methods for private properties. Even tho that isn&amp;rsquo;t a bad practice, he was distressed about how he missed the getter and setter syntax C# has. All you need to do is read more C# code! Or, read this post.&lt;/p&gt;
&lt;p&gt;So yeah, I guess this is a good C# crash course for those of us jumping head first into Unity &amp;hellip; Everytime I remember Unity uses C#, and an old version even, it makes me just so frustrated and want to rant for hours about how unfortunate that decision is. Let&amp;rsquo;s just forget that for now, and focus on C#.&lt;/p&gt;
&lt;h2&gt;Programming Carrots&lt;/h2&gt;
&lt;h3&gt;Getters and Setters&lt;/h3&gt;
&lt;p&gt;Well, let&amp;rsquo;s get this one out of the way already. C# allows developers to easily override a property&amp;rsquo;s getter and setter behavior using a very concise syntax that doesn&amp;rsquo;t involve defining new methods:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Test&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fullName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot; &amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;firstName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;components&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&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;First off, please don&amp;rsquo;t use this code. A space is by no means a good delimiter to use for splitting the first name and last name.&lt;/p&gt;
&lt;p&gt;Now, you can probably tell that the &lt;code&gt;firstName&lt;/code&gt; and &lt;code&gt;lastName&lt;/code&gt; properties, even though declared public, their setters are declared private. So, they can only be changed within the &lt;code&gt;Test&lt;/code&gt; class. This is a very cool way to quickly declare readonly properties.&lt;/p&gt;
&lt;p&gt;As for the &lt;code&gt;fullName&lt;/code&gt; property, it is a computed property. This means, everytime you try to access this property, you trigger the code within the &lt;code&gt;get&lt;/code&gt; block. Also, whenever you assign a new &lt;code&gt;value&lt;/code&gt; to this property, the &lt;code&gt;set&lt;/code&gt; block is triggered, and that new value is available in the &lt;code&gt;value&lt;/code&gt; variable, which is implicitly defined by the language.&lt;/p&gt;
&lt;h3&gt;Lambdas&lt;/h3&gt;
&lt;p&gt;Java didn&amp;rsquo;t have lambdas until very recently, but C# had those for a long time. Moreover, they have a really clean syntax, me likey. There is a downside, tho, and it is how the lambdas infer their types. You should either construct the lambda by explicitly defining the type (you can&amp;rsquo;t use &lt;code&gt;var&lt;/code&gt;) or by passing it directly to an argument expecting a callback.&lt;/p&gt;
&lt;p&gt;Here is where things get hairy. To define a lambda type in a clean way, we usually use &lt;code&gt;typedef&lt;/code&gt; in C/C++/ObjC. C# doesn&amp;rsquo;t have that, but instead, it has &lt;code&gt;delegate&lt;/code&gt;. Such an unfortunate keyword, but oh well. Let&amp;rsquo;s see how that works:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// this won&amp;#39;t work, since we don&amp;#39;t know the type of x&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// first declare the &amp;quot;function type&amp;quot;&lt;/span&gt;
&lt;span class="k"&gt;delegate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;CustomCallback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// now, we can define a lambda according to the signature above&lt;/span&gt;
&lt;span class="n"&gt;CustomCallback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just a quick tip, here are different ways to declare a lambda:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// pass a block of code, must terminate statements with &amp;quot;;&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;CustomCallback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// simple and concise&lt;/span&gt;
&lt;span class="c1"&gt;// no need for &amp;quot;;&amp;quot; at the end&lt;/span&gt;
&lt;span class="c1"&gt;// no need for a return call&lt;/span&gt;
&lt;span class="n"&gt;CustomCallback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;CustomCallback&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lambda&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Events&lt;/h3&gt;
&lt;p&gt;This one is a bit weird, but definitely unique to C#. Events. Another unfortunate keyword reservation &lt;code&gt;event&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Events basically help you simplify the observer pattern implementation, or even the reactor pattern. Instead of writing a data structure to hold the observers, then adding custom methods to add and remove observers, and finally iterating over the observers to trigger an event, just use &lt;code&gt;event&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;GlobalEvents&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// this is the delegate declaration we saw earlier&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="c1"&gt;// the event handler will be called for every new X value&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;delegate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;EventHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;newX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;static&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;event&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;EventHandler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;OnXUpdate&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;That&amp;rsquo;s it! We first defined the signature of the callback handlers we expect, and then declared a static event variable which we can register to. Let&amp;rsquo;s now use it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// add a handler that will print X&lt;/span&gt;
&lt;span class="c1"&gt;// we define so we can later remove it&lt;/span&gt;
&lt;span class="n"&gt;GlobalEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EventHandler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;x: &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;GlobalEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnXUpdate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// somewhere, when x gets updated and we want to send an event&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;GlobalEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnXUpdate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;GlobalEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnXUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;newX&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// when we decide to remove it&lt;/span&gt;
&lt;span class="n"&gt;GlobalEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OnXUpdate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;-=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So, in this case, we simply registered a lambda function to print the value of x using the &lt;code&gt;+=&lt;/code&gt; operator. By adding the handler, &lt;code&gt;OnXUpdate&lt;/code&gt; event is no longer &lt;code&gt;null&lt;/code&gt;, and actually has handlers. So, when we later decide to invoke it, it will trigger all the callbacks with the &lt;code&gt;newX&lt;/code&gt; value. And finally, when we are done, we use the &lt;code&gt;-=&lt;/code&gt; operator to do the cleanup.&lt;/p&gt;
&lt;h3&gt;Constructors&lt;/h3&gt;
&lt;p&gt;This one is a quick win. Instead of bothering with repeatedly initializing an object by setting various properties, you can simply initialize the parameters using some sort of initialization block:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// mendokusai&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// yatta!&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;More?&lt;/h3&gt;
&lt;p&gt;I am missing some important C# features, especially string interpolation using the &lt;code&gt;$&lt;/code&gt;, but that&amp;rsquo;s just because Unity doesn&amp;rsquo;t support it :( For the curious, I mean this is valid C# code (outside unity):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;quot;object: {obj.ToString()}&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Onto the OSS we march! Please don&amp;rsquo;t use the Unity forums nor packages as a source for learning C#, because they are (unfortunately) really poorly written. Most packages, even the most renowned animation libraries, have absolutely horrible code and practices (sorry to say, but it&amp;rsquo;s true). Instead, divert your eyes to Github, and tho shall see the light.&lt;/p&gt;</content><category term="posts"></category><category term="c#"></category></entry><entry><title>Alchemy</title><link href="https://mazyod.com/blog/2016/05/22/alchemy/" rel="alternate"></link><published>2016-05-22T01:29:27+00:00</published><updated>2016-05-22T01:29:27+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-22:/blog/2016/05/22/alchemy/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;At least, that&amp;rsquo;s what I feel like when writing Elixir code .. Like an Alchemist&amp;hellip; Constructing a bunch of flasks and burners, interconnected with a series of glass tubes, working seamlessly together to produce meth- erm.. I mean, Magic!&lt;/p&gt;
&lt;h2&gt;You High, Bro?&lt;/h2&gt;
&lt;p&gt;I can&amp;rsquo;t deny the high feeling …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;At least, that&amp;rsquo;s what I feel like when writing Elixir code .. Like an Alchemist&amp;hellip; Constructing a bunch of flasks and burners, interconnected with a series of glass tubes, working seamlessly together to produce meth- erm.. I mean, Magic!&lt;/p&gt;
&lt;h2&gt;You High, Bro?&lt;/h2&gt;
&lt;p&gt;I can&amp;rsquo;t deny the high feeling I get when working on Elixir. It&amp;rsquo;s just such a foreign language when compared to the crappy language I learned programming through (C++!). Without the static typing, without the generics, without the classes, without the inheritance &amp;hellip; Functional programming at it&amp;rsquo;s best, coupled with process-oriented architecture. Let me just spit out a few nice Elixir encounters I&amp;rsquo;ve had.&lt;/p&gt;
&lt;p&gt;.. On second thought, you should probably get an idea what the project itself is! Well, it&amp;rsquo;s a game backend! Yup, a game backend, with user profiles, matchmaking, rooms, leaderboards, game sessions, .. The whole 9-yards, basically. For a one developer, with absolutely no prior experience in shipping Elixir nor a game backend to do that would be considered insanity .. But here I am, 5 months into this project, with the most stable backend code I&amp;rsquo;ve ever written.&lt;/p&gt;
&lt;p&gt;DOOOOSHITE?!&lt;/p&gt;
&lt;h3&gt;It&amp;rsquo;s Erlang&lt;/h3&gt;
&lt;p&gt;Built on top of Erlang, this robust, mature, and fully-featured beast, Elixir is usually the only technology you&amp;rsquo;ll need to run the show. Within the Erlang ecosystem, you can take care of logging, background jobs, routing, &amp;hellip; etc. This cuts down the complexity tremendously!&lt;/p&gt;
&lt;p&gt;&lt;img alt="erlang is all you need" src="/images/erlang-one-is-all.png"&gt;&lt;/p&gt;
&lt;h3&gt;It&amp;rsquo;s Functional&lt;/h3&gt;
&lt;p&gt;Functional programming is by definition simple. The fact that no data is mutable just takes one more thing off your head, &amp;ldquo;Will an object change under my feet?&amp;rdquo; .. NEVER.&lt;/p&gt;
&lt;h3&gt;It&amp;rsquo;s Concurrent&lt;/h3&gt;
&lt;p&gt;The fact that it&amp;rsquo;s concurrent causes lots of misconception that such a feature results in complexity and overhead &amp;hellip; NO! That can&amp;rsquo;t be any further from the truth.&lt;/p&gt;
&lt;p&gt;The fact that it&amp;rsquo;s concurrent means you are safe from race conditions. It means you can isolate your code with minimal effort, and safely contain any error from causing the whole system to go down. It means .. profit.&lt;/p&gt;
&lt;h2&gt;Am I Truthly?&lt;/h2&gt;
&lt;p&gt;Ok, how can I convince anyone with all that rant above without some stories, eh? Sore-wa, dame desu.&lt;/p&gt;
&lt;h3&gt;Player State&lt;/h3&gt;
&lt;p&gt;First, let&amp;rsquo;s take a quick look at a very quirky problem that usually takes a ton of work to sort out .. Player state.&lt;/p&gt;
&lt;p&gt;You have player states everywhere! A game session contains the game state along with the connected players. A game room contains the players that joined, and could be chatting with one another. A matchmaking state tracks if the players accept the challenge or decline &amp;hellip; and so on.&lt;/p&gt;
&lt;p&gt;I am not even interested in exploring the solution in a traditional OOP language, since it would involve some sort of central crappy thing, OS threads, and stuff like that which just makes the system ever so error prone.&lt;/p&gt;
&lt;p&gt;What about Elixir?&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s literally as simple as spawning an Elixir process (Actor) that would manage the session. That&amp;rsquo;s it! The process would also monitor the player state, and make sure if the user disconnects, it processes the state accordingly. Let&amp;rsquo;s take an example.&lt;/p&gt;
&lt;p&gt;A player opens a game room by sending a &amp;ldquo;join&amp;rdquo; request with a certain ID format. Once the backend detects that the player is trying to join with an ID and room meta data, it will spawn a new &amp;ldquo;room state&amp;rdquo; process, assign it the room meta data, &lt;strong&gt;register the process globally using the room id&lt;/strong&gt;, then add the host player.&lt;/p&gt;
&lt;p&gt;Once the room is added, we broadcast its availability to all players. Once another player decides to join, the player sends the same &amp;ldquo;join&amp;rdquo; request, with that room id (but no room meta this time). Once the backend processes that request, it can easily fetch the room process using the ID provided, since remember! We did register the process globally using the room id! So, fetch it, add the user, and you are done!&lt;/p&gt;
&lt;p&gt;Well, at that point, the room state process will notice that it has 2 players, which means the room is filled! It will signal both players to proceed to the game, and broadcast an updated to the other players that the room is no longer available &amp;hellip; la fin!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I can never cover my journey with Elixir in one post, nor ten, but hopefully this will give you some urge to unravel this mighty beast, and look beyond the primitive tools education casts on us!&lt;/p&gt;</content><category term="posts"></category><category term="elixir"></category></entry><entry><title>Reboot!</title><link href="https://mazyod.com/blog/2016/05/22/reboot/" rel="alternate"></link><published>2016-05-22T00:59:54+00:00</published><updated>2016-05-22T00:59:54+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-05-22:/blog/2016/05/22/reboot/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Onto the reboot! Reboot what you ask?! Reboot the very fundamental reason I blog for! Looking back at how long it has been since I blogged, I realized that my actual productivity has an inverse relationship with the amount of articles I dish out .. So, this leads to two …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Onto the reboot! Reboot what you ask?! Reboot the very fundamental reason I blog for! Looking back at how long it has been since I blogged, I realized that my actual productivity has an inverse relationship with the amount of articles I dish out .. So, this leads to two choices:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Kill the blog (NO WAY!)&lt;/li&gt;
&lt;li&gt;Approach blogging differently&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;It&amp;rsquo;s not You; It&amp;rsquo;s Me&lt;/h2&gt;
&lt;p&gt;As I continued to write blog posts, I slowly felt inclined to write the highest quality posts I can muster, with details, graphics, references, &amp;hellip; etc. None of that matters!&lt;/p&gt;
&lt;p&gt;Looking back at the oldest posts, they were just purely spontaneous brain dumps that helped me track my progress, as well as have some sort of reference in the future regarding my work &amp;hellip; So, that&amp;rsquo;s what it&amp;rsquo;s gonna be!&lt;/p&gt;
&lt;p&gt;So, onto a reboot to clear these undesirable mutations, and restore the state to it&amp;rsquo;s initial pristine condition! &amp;hellip; Yes, I am so excited about blogging again, my brain is just conjuring all sorts of phrases and words I had no idea I ever knew &amp;hellip;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Check out the next post, coming out in a few&amp;hellip;&lt;/p&gt;</content><category term="posts"></category><category term="blog"></category></entry><entry><title>Swig Swag</title><link href="https://mazyod.com/blog/2016/02/16/swig-swag/" rel="alternate"></link><published>2016-02-16T11:31:02+00:00</published><updated>2016-02-16T11:31:02+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-02-16:/blog/2016/02/16/swig-swag/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Whenever programmers talk about programming languages, and how amazing those new languages are, they always end that discussion with how kick-ass C still is! It&amp;rsquo;s amazing how this primitive language is still at large and being used throughout the industry.&lt;/p&gt;
&lt;p&gt;While working on my game, I have built …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Whenever programmers talk about programming languages, and how amazing those new languages are, they always end that discussion with how kick-ass C still is! It&amp;rsquo;s amazing how this primitive language is still at large and being used throughout the industry.&lt;/p&gt;
&lt;p&gt;While working on my game, I have built the core artificial intelligence in C for maximum performance, and boy let me tell you &amp;hellip; That increased the performance by orders of magnitude.&lt;/p&gt;
&lt;p&gt;Performance wasn&amp;rsquo;t the only benefit I got from using C. Believe it or not, portability was another great feature, and the fact that I am using Unity to develop my game now didn&amp;rsquo;t change the fact that the AI is still written in C. Using C# and C in Unity has to be credited to SWIG, the star of our show tonight, so let&amp;rsquo;s see what that&amp;rsquo;s all about.&lt;/p&gt;
&lt;h2&gt;SWIG: Something Wonderful In Gloves&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://swig.org"&gt;SWIG&lt;/a&gt; is actually a very simple tool as a concept, but the value it offers is just too great. The basic idea is, integrating your C/C++ code with (almost) any other language.&lt;/p&gt;
&lt;p&gt;You see, most languages support calling C libraries natively, because C is the king that they turn back to when raw power is requried. Python has ctypes, C# has Marshaling, Java has JNI, ObjC just works with C, and so on&amp;hellip; So, where does SWIG fit in that picture?&lt;/p&gt;
&lt;p&gt;SWIG tells you as a developer, define the interface of your C/C++ library in a *.i file, and I&amp;rsquo;ll do the rest. Whoa! What about all that horrible JNI code I had to write? What about those weird marshaling rules C# requires? Nil of that is required&amp;hellip; Sweet!&lt;/p&gt;
&lt;p&gt;SWIG holds true to that (for C at least). I have simplified the interface of my AI a bit, and defined a very simple *.i file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;KodLogic&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cm"&gt;/* Includes the header in the wrapper code */&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;DamaCommon.h&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;DamaBot.h&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;DamaGameLogic.h&amp;quot;&lt;/span&gt;
&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;DamaUndoStack.h&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/* Parse the header file to generate wrappers */&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stdint.i&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;stdbool.i&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;DamaCommon.h&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;DamaBot.h&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;DamaGameLogic.h&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;DamaUndoStack.h&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yup, that was it. All I had to do then was run SWIG, and tell it that I want to be able to use this library from CSharp, and it replied, &amp;ldquo;Your command is my output&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;There isn&amp;rsquo;t really much else to cover. SWIG gave me all the CSharp files I needed to use the library, and I simply linked the library and dropped the CSharp files into my project. Everything was fly!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I guess if you ever had doubts about what game engine you&amp;rsquo;ll use, or what language you&amp;rsquo;ll be developing on as you write some core functionality, just keep in mind that C is there for you. Sure, it may not have Generics, dynamic collections, and other basic features, but it wasn&amp;rsquo;t so bad writing all those linked lists in pure C! lol, I&amp;rsquo;ll probably switch them later to a better dynamic array implementation, but for now, this will do.&lt;/p&gt;</content><category term="posts"></category><category term="swig"></category><category term="c"></category><category term="csharp"></category><category term="c#"></category><category term="unity"></category><category term="marshaling"></category><category term="library"></category><category term="dynamic"></category><category term="shared"></category><category term="bindings"></category><category term="callback"></category></entry><entry><title>MonoDevelop For N00bs</title><link href="https://mazyod.com/blog/2016/02/16/monodevelop-for-n00bs/" rel="alternate"></link><published>2016-02-16T09:53:31+00:00</published><updated>2016-02-16T09:53:31+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2016-02-16:/blog/2016/02/16/monodevelop-for-n00bs/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Over the last weekend, I had the pleasure of committing to learning all about MonoDevelop. For those of you not in the know, MonoDevelop is the default IDE shipped with Unity.&lt;/p&gt;
&lt;p&gt;In this article, I wanted to share my experience, and explain why I hated MonoDevelop so much in …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Over the last weekend, I had the pleasure of committing to learning all about MonoDevelop. For those of you not in the know, MonoDevelop is the default IDE shipped with Unity.&lt;/p&gt;
&lt;p&gt;In this article, I wanted to share my experience, and explain why I hated MonoDevelop so much in the past, and why I completely changed my mind now.&lt;/p&gt;
&lt;h2&gt;Setting Up&lt;/h2&gt;

&lt;p&gt;For whatever reason, it doesn&amp;rsquo;t matter, I haven&amp;rsquo;t had success in the past writing simple mono libraries using MonoDevelop. It was probably due to the fact that MonoDevelop refers to &amp;ldquo;projects&amp;rdquo; as &amp;ldquo;solutions&amp;rdquo;. That confused me quite a bit in the past. Also, when linking with libraries, you had to refer to them as &amp;ldquo;references&amp;rdquo;. Above all that, you had two different &amp;ldquo;solution&amp;rdquo; settings, the parent and the actual solution&amp;hellip; Talk about being spoiled by Xcode!&lt;/p&gt;
&lt;p&gt;So, anyways, the take away here is, you can do all the usual tasks any IDE does (duh!), but you need to be careful finding out what they are called, and how they are accessed.&lt;/p&gt;
&lt;h2&gt;Linking&lt;/h2&gt;
&lt;p&gt;So, now we know the basics of MonoDevelop&amp;hellip; Or at least, the basic terminologies. How about doing something useful this time? Let&amp;rsquo;s try linking some references!&lt;/p&gt;
&lt;p&gt;First, thing you might try is drag and drop. That will fail horribly, as MonoDevelop uses a very unique way for linking references.
All the referencing is actually done from within the references folder, located under your MonoDevelop solution:&lt;/p&gt;
&lt;h3&gt;Linking System References&lt;/h3&gt;
&lt;p&gt;So, in order to link a System reference, look no further than the first tab. Over there, you can simply choose your pick of System libraries to leverage withing your solution. This is actually the same way you would link to an existing solution within the same MonoDevelop Workspace. That solution will simply show up on the first tab, and will be built accordingly as the main target gets built. Nifty!&lt;/p&gt;
&lt;h3&gt;Linking To External Packages&lt;/h3&gt;
&lt;p&gt;It took me forever to figure this one out &amp;hellip; I kept dragging and dropping external libraries, adding them to /usr/local/lib, and even trying to link them through terminal. Non of that worked. I was getting frustrated when the solution was staring me in the face. It was under the third tab all along. Just navigate to that tab and hit &amp;ldquo;Browse&amp;hellip;&amp;rdquo;, import the library, and link!&lt;/p&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;p&gt;I had a real issue developing on MonoDevelop because I was never able to write proper unit tests. I found &amp;ldquo;NUnit&amp;rdquo;, but seriously, there is absolutely NO resource out there I found that explains how to integrate NUnit with your MonoDevelop solution. Most articles assumed you had NUnit integrated for some reason, maybe because most C# developers are on Windows? Who knows &amp;hellip; But the way to do it is to download the library and add it as a reference using the explanation above as a reference.&lt;/p&gt;
&lt;p&gt;Once you have the NUnit reference setup, you are all set! Simply follow any NUnit tutorial on how to write tests, and those are dime a dozen. Once you do, you will be rewarded with a really amazing UI that the MonoDevelop team have built for unit test writers:&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;For those OSX users develop Unity apps, I am sure you feel my pain as I write this&amp;hellip; I actually spent a whole day porting my logic code from C# to pure C, just because I could use Xcode Unit Tests!! After doing that, and integrating the C library with Unity using Swig, I realized that I can&amp;rsquo;t keep writing everything in C&amp;hellip; It&amp;rsquo;s just too much of a commitment. That&amp;rsquo;s when I decided to just spend a whole day learning this MonoDevelop tool and getting a basic Unit Tested library up and running&amp;hellip; Well, it didn&amp;rsquo;t stop there, actually. I was also able to get a basic C# client talking with a Phoenix server over websockets, yaaay.&lt;/p&gt;</content><category term="posts"></category><category term="null"></category></entry><entry><title>Contributing on Github</title><link href="https://mazyod.com/blog/2015/12/28/contributing-on-github/" rel="alternate"></link><published>2015-12-28T16:40:38+00:00</published><updated>2015-12-28T16:40:38+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-28:/blog/2015/12/28/contributing-on-github/</id><content type="html">&lt;p&gt;Well, here is a video blog post about contributing on &lt;a href="https://github.com"&gt;Github&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://youtu.be/eHOoCXy32Zc"&gt;Youtube link&lt;/a&gt;&lt;/p&gt;</content><category term="posts"></category><category term="opensource"></category><category term="youtube"></category><category term="github"></category><category term="contribution"></category><category term="video"></category><category term="software"></category><category term="development"></category></entry><entry><title>Kitz is Live!</title><link href="https://mazyod.com/blog/2015/12/19/kitz-is-live/" rel="alternate"></link><published>2015-12-19T20:11:44+00:00</published><updated>2015-12-19T20:11:44+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-19:/blog/2015/12/19/kitz-is-live/</id><summary type="html">&lt;h2&gt;Kitz Debut&lt;/h2&gt;
&lt;p&gt;I am officially announcing the simultaneous release of &lt;strong&gt;four&lt;/strong&gt; &lt;a href="http://kitz.io"&gt;Kitz&lt;/a&gt;. Well, &lt;a href="http://kitz.io"&gt;Kitz&lt;/a&gt; is the name of the project, and it is a collection of quality Swift libraries. Four of those libraries have been released today! In celebration of this prosperous release, I propose &lt;a href="https://www.youtube.com/watch?v=MwDhUt5ewKk"&gt;a toast&lt;/a&gt;! (Make sure you …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Kitz Debut&lt;/h2&gt;
&lt;p&gt;I am officially announcing the simultaneous release of &lt;strong&gt;four&lt;/strong&gt; &lt;a href="http://kitz.io"&gt;Kitz&lt;/a&gt;. Well, &lt;a href="http://kitz.io"&gt;Kitz&lt;/a&gt; is the name of the project, and it is a collection of quality Swift libraries. Four of those libraries have been released today! In celebration of this prosperous release, I propose &lt;a href="https://www.youtube.com/watch?v=MwDhUt5ewKk"&gt;a toast&lt;/a&gt;! (Make sure you come back and not enter the youtube paradox)&lt;/p&gt;
&lt;p&gt;These libraries were suppose to be a quick release of components that I wrote for an app, however, nothing is ever quick. It became apparent that the libraries had a very rigid API that fit that app, and that app alone. I abandoned the idea for a while since&amp;hellip;&lt;/p&gt;
&lt;p&gt;It came back to me after starting the next app, and needing those libraries badly. Now, with two different apps that need to use these libraries, I was able to generalize the APIs and make the libraries a lot more flexible .. That took time, along with all the tests and documentation. About 1.5 months worth of time.&lt;/p&gt;
&lt;p&gt;Thanks to encouraging contributions and feedback from various developers, I started to see potential in these libraries if done well. I guess I tried to invest just enough effort as to not make it suck, while still not putting in too much effort as to not regret it if it fails..&lt;/p&gt;
&lt;h2&gt;The Goodies&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll go over the most important points that makes &lt;a href="http://kitz.io"&gt;Kitz&lt;/a&gt; super awesome.&lt;/p&gt;
&lt;h3&gt;Self-Contained&lt;/h3&gt;
&lt;p&gt;Each library is self-contained, with minimal dependencies. The only dependencies allowed are Apple frameworks, since let&amp;rsquo;s face it, they are still needed instead of reinventing everything.&lt;/p&gt;
&lt;h3&gt;Minimalistic&lt;/h3&gt;
&lt;p&gt;Each library is also so small and tries to do one thing, and one thing only, right. You will notice that the libraries don&amp;rsquo;t need extensive documentation. The constraint here is to actually limit the documentation to a single page, the README file. &lt;/p&gt;
&lt;h3&gt;Real-World Requirements&lt;/h3&gt;
&lt;p&gt;All these libraries came from real-world apps pushed to production. They are not contrived nor built for the sake of using every single feature in Swift. They are genuinely built to make the life of the everyday Swift developer easier.&lt;/p&gt;
&lt;h3&gt;Testing&lt;/h3&gt;
&lt;p&gt;Every library is full tested, in production, as well as through the extensive unit tests. Unit tests are an extremely important part of these libraries, since we would like to evolve them as fast as possible without worrying too much about regression.&lt;/p&gt;
&lt;h3&gt;Continuous Integration&lt;/h3&gt;
&lt;p&gt;Last, but not least, &lt;a href="https://travis-ci.org/SwiftKitz"&gt;continuous integration, brought to you by Travis&lt;/a&gt;. This step is crucial to embrace the opensource community and their contribution. Without CI, it would be a tedious chore to manage contributions.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Give these libraries a try, open issues, submit PRs, I&amp;rsquo;ll even add you to the organization if you like. It&amp;rsquo;s meant to be a collaborative effort in a fun environment. Also, star, share and spread the ❤️.&lt;/p&gt;</content><category term="posts"></category><category term="opensource"></category><category term="github"></category><category term="code"></category><category term="swift"></category><category term="programming"></category><category term="library"></category><category term="kit"></category><category term="framework"></category><category term="cocoapods"></category><category term="carthage"></category><category term="tests"></category><category term="easy"></category><category term="simple"></category><category term="modular"></category><category term="ios"></category><category term="osx"></category><category term="tvos"></category><category term="watchos"></category><category term="travis"></category><category term="ci"></category><category term="developer"></category><category term="apple"></category></entry><entry><title>Nomad Review - San Diego</title><link href="https://mazyod.com/blog/2015/12/16/nomad-review-san-diego/" rel="alternate"></link><published>2015-12-16T23:27:10+00:00</published><updated>2015-12-16T23:27:10+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-16:/blog/2015/12/16/nomad-review-san-diego/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Since this has turned into a &amp;ldquo;Digial Nomad Journal&amp;rdquo;, it is only appropriate to mention the places I&amp;rsquo;ve been to and how that relates to the work environment. As I write this, I am one stop away from the final destination, but there is a lot to cover …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Since this has turned into a &amp;ldquo;Digial Nomad Journal&amp;rdquo;, it is only appropriate to mention the places I&amp;rsquo;ve been to and how that relates to the work environment. As I write this, I am one stop away from the final destination, but there is a lot to cover, anyway.&lt;/p&gt;
&lt;h2&gt;San Diego&lt;/h2&gt;
&lt;p&gt;This was my first destination in the US. A friend invited me over at a time when I needed to move to somewhere new. Arriving during mid September meant I could enjoy the best weather during the whole year. The first month there was perfect, considering it was new, lots to explore, and the weather of course.&lt;/p&gt;
&lt;p&gt;SD has a great location, being near LA and Irvine. This city lies in south California, just above the Mexican border. You must have access to a car over there, since it&amp;rsquo;s a very sparse city. With car access, you can also consider a 3 hour drive to LA for attending special events or the likes.&lt;/p&gt;
&lt;p&gt;Once I got over the SD hype, I realized there isn&amp;rsquo;t much to it beside that. It was hard to find working places. The downtown was nice, but not extensive. Almost everything was over-priced, but that&amp;rsquo;s all of California, really. I do have to say, they had some great food options. Sushi, Gourmets, fast food, and Indian options were plentiful.&lt;/p&gt;
&lt;p&gt;One really painful realization was the lack of a real tech scene or tech presence. Being software developers we usually thrive in communities and collaborative environments. That was non-existent.&lt;/p&gt;
&lt;p&gt;To wrap up here, I&amp;rsquo;d give this place a stay of 1 - 2 months max. If possible, try staying near the downtown, since that&amp;rsquo;s where all the stuff is happening. It is a very fun place to be for tourists, no one can deny that, but not so much for digital nomads.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;With San Diego out of the picture, it was time to aim for something new. The next destination was Boston, MA. We will hopefully be covering that in the next part.&lt;/p&gt;</content><category term="posts"></category><category term="nomad"></category><category term="travel"></category><category term="work"></category><category term="remote"></category><category term="workplace"></category><category term="finance"></category><category term="culture"></category><category term="atmosphere"></category></entry><entry><title>Constructing URLs in Foundation</title><link href="https://mazyod.com/blog/2015/12/14/constructing-urls-in-foundation/" rel="alternate"></link><published>2015-12-14T19:23:26+00:00</published><updated>2015-12-14T19:23:26+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-14:/blog/2015/12/14/constructing-urls-in-foundation/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;While building &lt;a href="https://github.com/SwiftKitz/Appz"&gt;Appz&lt;/a&gt;, we had to deal with a lot of URLs; constructing URLs for both opening other apps as well as websites.&lt;/p&gt;
&lt;p&gt;Once &lt;a href="https://github.com/SwiftKitz/Appz/pull/6"&gt;the first Kitz contributor&lt;/a&gt; started submitting pull requests, it was apparent that it was error prone for developers to add support for other apps. The …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;While building &lt;a href="https://github.com/SwiftKitz/Appz"&gt;Appz&lt;/a&gt;, we had to deal with a lot of URLs; constructing URLs for both opening other apps as well as websites.&lt;/p&gt;
&lt;p&gt;Once &lt;a href="https://github.com/SwiftKitz/Appz/pull/6"&gt;the first Kitz contributor&lt;/a&gt; started submitting pull requests, it was apparent that it was error prone for developers to add support for other apps. The API was expecting a fully constructed URL string, so it was the responsibility of the app URL definitions to perform the escaping and full URL construction, which didn&amp;rsquo;t make sense. That is too much burden for all the App definitions collectively.&lt;/p&gt;
&lt;p&gt;Instead .... Actually, it&amp;rsquo;s about time we transitioned into the blog post!&lt;/p&gt;
&lt;h2&gt;EZ URL Definitions&lt;/h2&gt;
&lt;p&gt;So, the API was rewritten to make the definitions easier to write and maintain. For that, a &lt;code&gt;Path&lt;/code&gt; class was introduced. It simply gives a very convenient way to define a url path by assigning a list of path components as well as query parameters, without worrying how they will be encoded in the end.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;pathComponents&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;queryParameters&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;String&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;Honestly, the &lt;code&gt;Path&lt;/code&gt; class is a bit redundant to something that &lt;code&gt;NSURL&lt;/code&gt; or &lt;code&gt;NSURLComponents&lt;/code&gt; should already do, but they require lots of boilerplate code to get right, so we opted-in for a custom class.&lt;/p&gt;
&lt;h2&gt;EZ URL Encoding&lt;/h2&gt;
&lt;p&gt;So, now we have the path definition, but how do we actually encode it to a URL? I stumbled upon a bunch of answers on stackoverflow, but almost all of them had annoying drawbacks &amp;hellip; Until I came across &lt;code&gt;NSURLQueryItem&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s take a look at the classes Foundation offers for dealing with URLs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;NSURL&lt;/code&gt;: Base class for representing a URL&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSURLComponents&lt;/code&gt;: Factory class for assembling URLs (iOS 7+)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NSURLQueryItem&lt;/code&gt;: a name/value pair for a URL query (iOS 8+)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;NSURL&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;d assume anyone who spent a few weeks writing Foundation based application will have definitely come across &lt;code&gt;NSURL&lt;/code&gt;. It is used in the &lt;code&gt;NSFileManager&lt;/code&gt; and &lt;code&gt;NSBundle&lt;/code&gt; APIs for dealing with filepaths, &lt;code&gt;NSURLSession&lt;/code&gt; for web resources, and many other use cases.&lt;/p&gt;
&lt;p&gt;The biggest caveat about &lt;code&gt;NSURL&lt;/code&gt; that developers miss is its immutability. It has a very shallow API for constructing and changing the underlying URL, and when it does, it would return a new &lt;code&gt;NSURL&lt;/code&gt; instance. The most famous method that fits this criteria is &lt;code&gt;URLByAppendingPathComponent:&lt;/code&gt;, which returns a new &lt;code&gt;NSURL?&lt;/code&gt; after attempting to append the passed value as a path. Not very helpful, as we well see later.&lt;/p&gt;
&lt;h3&gt;NSURLComponents&lt;/h3&gt;
&lt;p&gt;As mentioned, this class acts as a factory for &lt;code&gt;NSURL&lt;/code&gt; instances. You can initialize an instance of &lt;code&gt;NSURLComponents&lt;/code&gt;, then start customizing how the resulting &lt;code&gt;NSURL&lt;/code&gt; instances will be. Let&amp;rsquo;s see an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;comps&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;NSURLComponents&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;comps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;https&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;comps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;github.com&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;comps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;/SwiftKitz/Appz&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;comps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;queryItems&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;NSURLQueryItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;example&amp;quot;&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="s"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="n"&gt;comps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;URL&lt;/span&gt; &lt;span class="c1"&gt;// https://github.com/SwiftKitz/Appz?example=1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The beauty of the example above is the absolute lack of special characters, like colons &lt;code&gt;:&lt;/code&gt;, question marks &lt;code&gt;?&lt;/code&gt;, equal sign &lt;code&gt;=&lt;/code&gt;, and ampersands &lt;code&gt;&amp;amp;&lt;/code&gt;. That is all taken care of for us by this lovely class.&lt;/p&gt;
&lt;h3&gt;NSURLQueryItem&lt;/h3&gt;
&lt;p&gt;You should haven&amp;rsquo;t gotten the gist of this class from the example above. It is a very basic class that represents a name/value pair in a URL query. The cool part about this class is that it takes care of encoding all special characters that might appear in the query parameters. Hence, you should use it!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;It is very important for developers, especially seasoned ones, to continuously research for better ways to tasks they are used to performing, like constructing an &lt;code&gt;NSURL&lt;/code&gt; instance. New, better APIs might be available, and leveraging them might resolve hidden bugs in your code, and probably help speed your development process further.&lt;/p&gt;</content><category term="posts"></category><category term="Foundation"></category><category term="NSURL"></category><category term="query"></category><category term="path"></category><category term="escape"></category><category term="hardcode"></category><category term="clean"></category><category term="snippet"></category><category term="tutorial"></category><category term="ios"></category><category term="osx"></category><category term="swift"></category></entry><entry><title>Developing tvOS Apps</title><link href="https://mazyod.com/blog/2015/12/10/developing-tvos-apps/" rel="alternate"></link><published>2015-12-10T00:28:04+00:00</published><updated>2015-12-10T00:28:04+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-10:/blog/2015/12/10/developing-tvos-apps/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Hey, Maz. We would like a port of our iOS app on AppleTV within one month max&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My response ....&lt;/p&gt;
&lt;p&gt;&lt;img alt="One does not simply copy paste iOS code into tvos" src="/images/one-does-not-simple-tvos.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Yes, lots of work is involved in porting an app to tvOS, but it wasn&amp;rsquo;t too bad all things considered. Let&amp;rsquo;s see the highlights of this experience.&lt;/p&gt;
&lt;h2&gt;RingoTV …&lt;/h2&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Hey, Maz. We would like a port of our iOS app on AppleTV within one month max&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My response ....&lt;/p&gt;
&lt;p&gt;&lt;img alt="One does not simply copy paste iOS code into tvos" src="/images/one-does-not-simple-tvos.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Yes, lots of work is involved in porting an app to tvOS, but it wasn&amp;rsquo;t too bad all things considered. Let&amp;rsquo;s see the highlights of this experience.&lt;/p&gt;
&lt;h2&gt;RingoTV&lt;/h2&gt;
&lt;h3&gt;TVJS&lt;/h3&gt;
&lt;p&gt;Before doing anything with the tvOS app, I wanted to get my hands dirty with some basic UI programming. First thing I decided to do was try out the new &lt;a href="https://developer.apple.com/library/tvos/documentation/TVMLJS/Reference/TVJSFrameworkReference/index.html"&gt;TVML and TVJS APIs&lt;/a&gt;. They seem to be recommended and are quite a streamlined way of building tvOS apps&amp;hellip; Why not?&lt;/p&gt;
&lt;p&gt;It was terrible idea. I easily threw a whole week worth of work out the window because&amp;hellip; &lt;a href="https://www.destroyallsoftware.com/talks/wat"&gt;JavaScript&lt;/a&gt;. I dread this language&amp;hellip; It was hard to figure your way around, everything is so streamlined and also rigid, so you have to follow some pretty dumb and strict syntax and methods to do things.&lt;/p&gt;
&lt;p&gt;The ultimate bad thing about this was the need to rewrite all the code that deals with API calls, parses the JSON, authentication, &amp;hellip; etc. Just. Too. Much. Work.&lt;/p&gt;
&lt;h3&gt;Dependencies&lt;/h3&gt;
&lt;p&gt;I spent a lot of time looking around for ports of dependencies we were using in the project, but without luck. We were using the monolithic &lt;a href="https://github.com/RestKit/RestKit"&gt;RestKit&lt;/a&gt; as well as &lt;a href="https://github.com/magicalpanda/MagicalRecord"&gt;MagicalRecord&lt;/a&gt;. Both don&amp;rsquo;t support tvOS, how nice&amp;hellip;&lt;/p&gt;
&lt;p&gt;Then, I spent some time looking for good forks, without luck. I tried to fork these projects, update dependencies, but RestKit dependency tree is actually a hedge maze. That didn&amp;rsquo;t go well at all&amp;hellip;&lt;/p&gt;
&lt;p&gt;I abandoned all hope of coming up with an elegant solution at this point, and decided to just download all the sources, and drop them into the project. Using some regex, the imports were resolved, and deleting all the fat from the projects, they were up and running perfectly well withing a couple of hours. Yay!! Porting RestKit to tvOS was definitely the biggest challenge in this project, and was actually simple enough.&lt;/p&gt;
&lt;h3&gt;UIKit&lt;/h3&gt;
&lt;p&gt;This was an immediate win, and immediately felt like the right solutions. Creating a storyboard, and adding simple collection views and navigation controllers got me up and running in no time, thanks to reusing my iOS experience.&lt;/p&gt;
&lt;p&gt;At that point, an important decision was made, which is to simplify the tvOS app as much as possible, such that it would fit one storyboard. We don&amp;rsquo;t have time for bells and whistles, so constraints had to be put in place early on to ensure the project will make it.&lt;/p&gt;
&lt;p&gt;I would say that I only faced really few major issues, and they were pretty manageable. Keep in mind, I wanted to reuse as much of the iOS code as possible.&lt;/p&gt;
&lt;h4&gt;SELECTION&lt;/h4&gt;
&lt;p&gt;OK, so I ported the dependencies, then ported the models, and those worked great. Now, time to port the UI, or at least try to replicate it. The biggest issue here was selection. You don&amp;rsquo;t have a finger touching your UI, it&amp;rsquo;s now a mouse pad thingie!&lt;/p&gt;
&lt;p&gt;It was actually really simple thanks to the built-in &amp;ldquo;Focus Engine&amp;rdquo;. Apple has already incorporated most of the selection logic needed, you just need to update your UI in respond to an item being focused/unfocused on.&lt;/p&gt;
&lt;p&gt;For &lt;code&gt;UITableView&lt;/code&gt; and &lt;code&gt;UIButton&lt;/code&gt;, it just worked out of the box. However, &lt;code&gt;UICollectionView&lt;/code&gt; required some work to get up and running &amp;hellip; The work for the most part was just:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userInteractionEnabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="n"&gt;imageView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;adjustsImageWhenAncestorFocused&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Amazing! But there was an edge case where we showed a label when the image wasn&amp;rsquo;t available, so we had to handle the &lt;code&gt;UILabel&lt;/code&gt; changing colors on focus like so (pardon the objc):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;coordinator&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;addCoordinatedAnimations&lt;/span&gt;&lt;span class="o"&gt;:^&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nextFocusedView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;UIColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whiteColor&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;UIColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;darkGrayColor&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;previouslyFocusedView&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;backgroundColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;UIColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;colorWithRGB&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mh"&gt;0x8C8988&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;textColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;UIColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;whiteColor&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;completion&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="nb"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;NAVIGATION&lt;/h4&gt;
&lt;p&gt;The final issue was navigation. After implementing a &lt;code&gt;UINavigationController&lt;/code&gt;, the app kept entering background after pressing the Menu button on the remote. We needed to explicitly handle that event to make sure it controls the navigation controller instead.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kr"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;pressesBegan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;presses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="bp"&gt;UIPress&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;withEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;UIPressesEvent&lt;/span&gt;&lt;span class="p"&gt;?)&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;presses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;first&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Menu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kc"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pressesBegan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;presses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;withEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&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="kr"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;pressesEnded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;presses&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="bp"&gt;UIPress&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="n"&gt;withEvent&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;UIPressesEvent&lt;/span&gt;&lt;span class="p"&gt;?)&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;presses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;first&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Menu&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kc"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pressesEnded&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;presses&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;withEvent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;detailNavigationController&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popViewControllerAnimated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&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 had a &lt;code&gt;UISplitViewController&lt;/code&gt; as the main controller in the app, so these methods were added there. Then, we get the navigation controller of the detail view controller and pop there. Maybe a check should be added to make sure the navigation controller isn&amp;rsquo;t already at root, but meh. This works.&lt;/p&gt;
&lt;h3&gt;Authentication&lt;/h3&gt;
&lt;p&gt;This is the last piece of the puzzle, and honestly, still unresolved. I&amp;rsquo;ve communicated with the backend engineer that we need new endpoints for implementing authentication on tvOS, since we can&amp;rsquo;t expect the user to enter their login using the remote.&lt;/p&gt;
&lt;p&gt;We decided to go with something &lt;a href="http://get.digits.com/blog/introducing-digits-for-tvos"&gt;similar to what digits does&lt;/a&gt;. That was super simple to implement on the tvOS side, but still waiting for the backend to update the APIs.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;YES, that was pretty much it. The rest of the implementation went super smooth. The models with &lt;code&gt;NSFetchedResultsController&lt;/code&gt; worked seamlessly with the tvOS &lt;code&gt;UICollectionViewController&lt;/code&gt;s. The process of hooking the models with the new UI was just a single good afternoon&amp;rsquo;s worth of work.&lt;/p&gt;</content><category term="posts"></category><category term="tvos"></category><category term="uikit"></category><category term="programming"></category><category term="ios"></category><category term="xcode"></category><category term="swift"></category><category term="appletv"></category><category term="apple"></category><category term="introduction"></category><category term="tutorial"></category><category term="dependencies"></category><category term="restkit"></category></entry><entry><title>Swifty NSNotificationCenter</title><link href="https://mazyod.com/blog/2015/12/07/swifty-nsnotificationcenter/" rel="alternate"></link><published>2015-12-07T12:32:25+00:00</published><updated>2015-12-07T12:32:25+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-07:/blog/2015/12/07/swifty-nsnotificationcenter/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is another post about &lt;a href="http://Kitz.io"&gt;Kitz&lt;/a&gt;. This time we will be looking at &lt;a href="https://github.com/SwiftKitz/Notificationz"&gt;Notificationz&lt;/a&gt;. We will cover the motivation behind the library, and how it can easily turn your code around to be a lot more readable.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;One of the frequent pain points of iOS programming is …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This is another post about &lt;a href="http://Kitz.io"&gt;Kitz&lt;/a&gt;. This time we will be looking at &lt;a href="https://github.com/SwiftKitz/Notificationz"&gt;Notificationz&lt;/a&gt;. We will cover the motivation behind the library, and how it can easily turn your code around to be a lot more readable.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;One of the frequent pain points of iOS programming is dealing with &lt;code&gt;NSNotificationCenter&lt;/code&gt;. It is has very &amp;ldquo;bulky&amp;rdquo; syntax, you must juggle a lot of constant string, and make sure you add and cleanup your observers properly. All this causes a lot of boiler plate code, and worst part is that it is all over the place:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SomeClass&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 1&lt;/span&gt;
        &lt;span class="bp"&gt;NSNotificationCenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultCenter&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;addObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;onApplicationDidBecomeActive:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UIApplicationDidBecomeActive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;deinit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// 2&lt;/span&gt;
        &lt;span class="bp"&gt;NSNotificationCenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultCenter&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;removeObserver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;onApplicationDidBecomeActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notif&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;NSNotification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Do stuff&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;As you see, three different places are littered with &lt;code&gt;NSNotificationCenter&lt;/code&gt; dependency, not to mention this bulky API. Not only that, but you may mistakenly observe an event that sends notification on a background thread, then update your UI &amp;hellip; BOOM. So, now you have to wrap it around &lt;code&gt;dispatch_async&lt;/code&gt; &amp;hellip; This is getting really ugly.&lt;/p&gt;
&lt;p&gt;We want to do something about that&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Import Notificationz&lt;/h2&gt;
&lt;p&gt;That&amp;rsquo;s where Notificationz comes in. It is super light-weight and simple, and just aims to solve this problem. We introduce only 2 classes, and you go from the previous syntax to this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;Notificationz&lt;/span&gt;

&lt;span class="c1"&gt;// Define your global helper only once for all files&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;center&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;NSNotificationCenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultCenter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;NC&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NotificationCenterAdapter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notificationCenter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Sample&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;keyboardObserver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;reachabilityObserver&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Observer&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;

    &lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;keyboardObserver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;NC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observeUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UIKeyboardWillShowNotification&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="kr"&gt;unowned&lt;/span&gt; &lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="kc"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
            &lt;span class="c1"&gt;// you can write your handler code here, maybe call another function&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;That&amp;rsquo;s it! The code above shows you 3 important concepts:&lt;/p&gt;
&lt;h3&gt;RAII&lt;/h3&gt;
&lt;p&gt;You don&amp;rsquo;t have to do any cleanup yourself. When this object is dealloc&amp;rsquo;d, the observer variable will automatically get dealloc&amp;rsquo;d and remove the observer from &lt;code&gt;NSNotificationCenter&lt;/code&gt;. If you like, you can prematurely remove the observer by simply setting the value of the variable to &lt;code&gt;nil&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;keyboardObserver&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Ensure Main Thread&lt;/h3&gt;
&lt;p&gt;The library provides &lt;code&gt;observe&lt;/code&gt; and &lt;code&gt;observeUI&lt;/code&gt;. As the name implies, observing for UI will guarantee that the notification block will be executed on the main thread. This means you can safely update your UI from the callback block.&lt;/p&gt;
&lt;h3&gt;Conciseness&lt;/h3&gt;
&lt;p&gt;Now, if you want to know what this class observes, all you do is look at the instance variables. They tell you all you need to know about what this class observes.&lt;/p&gt;
&lt;p&gt;Also, once you observe a notification name, you immediately follow with the handler code. This makes sure that you don&amp;rsquo;t deal with &amp;ldquo;strings&amp;rdquo; that may easily break when the selector is removed for renamed.&lt;/p&gt;
&lt;h2&gt;Extra Goodness&lt;/h2&gt;
&lt;p&gt;The library offers other helpful functions that complement the &lt;code&gt;observe&lt;/code&gt; functionality:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;NC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;call:&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// normal add observer&lt;/span&gt;
&lt;span class="n"&gt;NC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;observe&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;notification&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;  &lt;span class="c1"&gt;// observe using blocks&lt;/span&gt;
&lt;span class="n"&gt;NC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ten-hut!&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;             &lt;span class="c1"&gt;// post a notification&lt;/span&gt;
&lt;span class="n"&gt;NC&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;                  &lt;span class="c1"&gt;// remove from nsCenter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you want to make your code look pretty again, take a look at this library, and consider dropping it in. Contributions welcome, and there are some other &lt;a href="https://github.com/SwiftKitz/Appz"&gt;pretty cool&lt;/a&gt; libraries as part of &lt;a href="http://kitz.io"&gt;Kitz&lt;/a&gt;&lt;/p&gt;</content><category term="posts"></category><category term="swift"></category><category term="foundation"></category><category term="kitz"></category><category term="nsnotification"></category><category term="nsnotificationcenter"></category><category term="library"></category><category term="github"></category><category term="opensource"></category><category term="programming"></category><category term="code"></category><category term="raii"></category></entry><entry><title>Playing With ReactiveCocoa</title><link href="https://mazyod.com/blog/2015/12/05/playing-with-reactivecocoa/" rel="alternate"></link><published>2015-12-05T02:10:51+00:00</published><updated>2015-12-05T02:10:51+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-05:/blog/2015/12/05/playing-with-reactivecocoa/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;ReactiveCocoa is a long standing library, it&amp;rsquo;s by no means something new. The cool kids were already high on &lt;a href="https://github.com/ReactiveCocoa/ReactiveCocoa"&gt;ReactiveCocoa&lt;/a&gt; since the Objective-C days. Alas, it wasn&amp;rsquo;t something I decided to try before today.&lt;/p&gt;
&lt;p&gt;Through this article, I&amp;rsquo;d like to cover my initial impressions in using …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;ReactiveCocoa is a long standing library, it&amp;rsquo;s by no means something new. The cool kids were already high on &lt;a href="https://github.com/ReactiveCocoa/ReactiveCocoa"&gt;ReactiveCocoa&lt;/a&gt; since the Objective-C days. Alas, it wasn&amp;rsquo;t something I decided to try before today.&lt;/p&gt;
&lt;p&gt;Through this article, I&amp;rsquo;d like to cover my initial impressions in using ReactiveCocoa with Swift, especially because of the insane potential that it has to dramatically streamline apps.&lt;/p&gt;
&lt;h2&gt;Reactions&lt;/h2&gt;
&lt;p&gt;I will not sit here and talk about reactive programming and pretend I am an expert, because I am not. I will simply present a metaphor that I like to keep in mind, then share a bunch of useful links on the topic. I hope you are familiar with circuit boards, because that will be the basis of our metaphor.&lt;/p&gt;
&lt;p&gt;When designing a circuit board, the usual parts we tend to use often are the power source, resistor, capacitor, inductor, &amp;hellip; etc. The power source would be the &amp;ldquo;producer&amp;rdquo;, such as a battery, and the resistor would be the &amp;ldquo;consumer&amp;rdquo;, such as a lamp. Then, we have other parts that incur various effects. For example, we can think of a capacitor as a gatekeeper, since it only allows alternating current to pass, and serves as open-circuit when full.&lt;/p&gt;
&lt;p&gt;Now, you as the circuit designer, would probably start with the power source, and decide how the current should flow, doing any processing as necessary. For example, you may add two power sources, and only switch on the light if both are active.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s pretty much it, as far as I know. Reactive programming has &amp;ldquo;signals&amp;rdquo; instead of power sources, and you observe these signals, react to them, apply various processing routines around them, and something else happens as a result.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://reactivex.io/"&gt;See ReactiveX&lt;/a&gt;
&lt;a href="https://en.wikipedia.org/wiki/Reactive_programming"&gt;See wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Functional Reactions&lt;/h2&gt;
&lt;p&gt;Now all that is nice and dandy, but how about a practical example with Swift and ReactiveCocoa 4.0 alpha4?&lt;/p&gt;
&lt;p&gt;The example we will take a look at is something I am actually using in a shipping app, so it should be practical and useful. I admit, though, it&amp;rsquo;s the same example you&amp;rsquo;d see everywhere else&amp;hellip; Taking user input, validating, then reacting with colors and enable/disable button, specifically for login and signup.&lt;/p&gt;
&lt;p&gt;What does this look like?&lt;/p&gt;
&lt;p&gt;&lt;img alt="Reactive Login" src="/images/reactive-login.png"&gt;&lt;/p&gt;
&lt;p&gt;What about teh codez?&lt;/p&gt;
&lt;p&gt;First, we simply store the actors in our little reactive play in local variables. We will see later this will prove useful for many things, like breaking retain cycles.&lt;/p&gt;
&lt;p&gt;Note how we store &lt;code&gt;NameValidator.validate&lt;/code&gt; into an array. This is simple a static method that takes in a &lt;code&gt;String&lt;/code&gt; and returns a &lt;code&gt;Bool&lt;/code&gt;. This means, &lt;code&gt;validators&lt;/code&gt; is an array of functions that all take a &lt;code&gt;String&lt;/code&gt; and return a &lt;code&gt;Bool&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Prepare actors (avoid retain cycle)&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;button&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;signupButton&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;fields&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;firstnameField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;lastnameField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;mobileNumberField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;validators&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="n"&gt;NameValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;NameValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;MobileNumberValidator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we prepare the signals we would like to observe and process. The signal we are interested in is the &lt;code&gt;rac_textSignal&lt;/code&gt;. It emits a signal whenever the &lt;code&gt;text&lt;/code&gt; property of &lt;code&gt;UITextField&lt;/code&gt; changes.&lt;/p&gt;
&lt;p&gt;We create the signals by first &lt;code&gt;zip&lt;/code&gt;-ing the field with its validator, the iterating on those by getting the text signal and mapping its result to the validator. This is the first arrow in the graph above. The signal emits a &lt;code&gt;String&lt;/code&gt; each time &lt;code&gt;text&lt;/code&gt; changes, then we pass that to the validator, returning for us a &lt;code&gt;Bool&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Prepare signals&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;signals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;validators&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="bp"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;

    &lt;span class="n"&gt;field&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rac_textSignal&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="nb"&gt;String&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;Now, we simply add our process block that will set the color based on whether the validator returned &lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We iterate a &lt;code&gt;zip&lt;/code&gt;-ed fields and signals this time, and for each signal we add a process block that will set the field &lt;code&gt;valid&lt;/code&gt; property to the validator result. This is actually a &lt;code&gt;UITextField&lt;/code&gt; subclass that has a &lt;code&gt;valid&lt;/code&gt; property, which upon being set, updates the colors.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Apply color subscribers&lt;/span&gt;
&lt;span class="n"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;forEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signal&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;signal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribeNext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;field&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;valid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="bp"&gt;NSNumber&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;boolValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, this may be achieved in a better way by including this code in the &lt;code&gt;UITextField&lt;/code&gt; subclass, then assigning the validator to the &lt;code&gt;UITextField&lt;/code&gt; itself. That&amp;rsquo;s not a bad approach, I might go with that actually.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s see how we can reduce the three signals emitted from the &lt;code&gt;textfields&lt;/code&gt; into one signal using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;. We only enable the sign up button if all textfields validate, after all.&lt;/p&gt;
&lt;p&gt;First, we &amp;ldquo;combine&amp;rdquo; the signals, which simply puts all the latest signal results into a &lt;code&gt;RACTuple&lt;/code&gt;. Then, we &amp;ldquo;normalize&amp;rdquo; the &lt;code&gt;RACTuple&lt;/code&gt; using &lt;code&gt;allObjects&lt;/code&gt;. After that, we cast that array to &lt;code&gt;[NSNumber]&lt;/code&gt;, and reduce that using &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt;, meaning &lt;em&gt;all&lt;/em&gt; signals must be &lt;code&gt;true&lt;/code&gt;. Finally, we add our custom process block, which updates the &lt;code&gt;button&lt;/code&gt; enabled state to the reduced result we just computed!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// Apply button state subscriber&lt;/span&gt;
&lt;span class="n"&gt;RACSignal&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;combineLatest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;signals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="n"&gt;RACTuple&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;allObjects&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="bp"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;NSNumber&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;boolValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;$1&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="n"&gt;subscribeNext&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="bp"&gt;NSNumber&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;boolValue&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I really have no more things to say, it almost works like magic. All this is a one time setup in &lt;code&gt;viewDidLoad&lt;/code&gt;, which just makes life way easier.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I always try to be honest and blunt about my thoughts, so here is the last bit. I would probably never use &lt;code&gt;ReactiveCocoa&lt;/code&gt; in a long term project that I need to personally maintain. Dealing with Swift flux is painful enough, and thus apps that I look to maintain have absolutely minimum external dependencies, &lt;em&gt;especially&lt;/em&gt; enormous libraries that I can just fork and build my own version of.&lt;/p&gt;
&lt;p&gt;Then, why did I use it? I am working for a client on a simple app, and the goal here is to cut costs and roll out an app ASAP. This app won&amp;rsquo;t be doing any insane UI/UX features, it&amp;rsquo;s all about building a small footprint application to validate the market. Hence, ReactiveCocoa saved me a whole bunch of extra code I would otherwise had to write and prolong the project.&lt;/p&gt;
&lt;p&gt;P.S. I really don&amp;rsquo;t get developers who refuse to check in the project&amp;rsquo;s podspec into the main repo. Something about not willing to maintain it, or incur the burden &amp;hellip; I mean, c&amp;rsquo;mon, just do the whole iOS community a solid here and check it in&amp;hellip;&lt;/p&gt;</content><category term="posts"></category><category term="ios"></category><category term="swift"></category><category term="xcode"></category><category term="reactive"></category><category term="programming"></category><category term="functional"></category><category term="reactivecocoa"></category><category term="github"></category><category term="framework"></category><category term="library"></category><category term="review"></category><category term="design"></category><category term="uikit"></category></entry><entry><title>Freelancing Stories</title><link href="https://mazyod.com/blog/2015/12/02/freelancing-stories/" rel="alternate"></link><published>2015-12-02T11:24:16+00:00</published><updated>2015-12-02T11:24:16+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-12-02:/blog/2015/12/02/freelancing-stories/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It wouldn&amp;rsquo;t be unusual to be sitting at some day job thinking&amp;hellip; Wouldn&amp;rsquo;t it be great to be one&amp;rsquo;s own boss? Taking vacations anytime, no one pestering you about what you wear or when you wake up &amp;hellip; Sounds like the perfect lifetime plan! But how&amp;hellip;&lt;/p&gt;
&lt;p&gt;Of …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It wouldn&amp;rsquo;t be unusual to be sitting at some day job thinking&amp;hellip; Wouldn&amp;rsquo;t it be great to be one&amp;rsquo;s own boss? Taking vacations anytime, no one pestering you about what you wear or when you wake up &amp;hellip; Sounds like the perfect lifetime plan! But how&amp;hellip;&lt;/p&gt;
&lt;p&gt;Of course! Why not try freelancing? You pick your own projects, finish work at your own pace, heck, you get get to decide what your salary is gonna be. You can&amp;rsquo;t possibly go wrong there? .. &lt;strong&gt;WRONG&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Negotiation&lt;/h2&gt;
&lt;p&gt;Before any project takes place, you must actually find a project. If you are a software developer, you simply don&amp;rsquo;t have a problem there. Period. Clients are everywhere, with so much variety, there is literally a client for any weird scenario you may think of. That&amp;rsquo;s why I decided to skip the discovery phase and start with the negotiation phase right off the bat.&lt;/p&gt;
&lt;h3&gt;Lesson 1: People Matter&lt;/h3&gt;
&lt;p&gt;Negotiating purely on the project scope and pay spells out disaster for you as a freelancer. First think you should care about are the people you&amp;rsquo;ll be working for.&lt;/p&gt;
&lt;p&gt;One of my clients I worked for wanted a pretty simple and straight-forward iOS app. They had absolutely no clue how developing iOS apps work, and I thought to myself: &amp;ldquo;That&amp;rsquo;s great! I get to set my own rules and standards, and teach them along the way&amp;rdquo;. We agreed on the price, money was paid on time and all, and the project started&amp;hellip;&lt;/p&gt;
&lt;p&gt;As the project progressed, I first kept working on the UI side, throwing suggestions at the client, and the client was happy. The client was seeing progress, listening to my feedback, and only synced up with me once a week.&lt;/p&gt;
&lt;p&gt;By the end of the first sprint, I showed the client a complete basic app fully functional, but without backend integration. All the data in the app was dummy data, but at least the UI implementation was almost perfect. The client sent back some minor feedback regarding the UI demo, and decided to move forward with the project and start integrating the backend &amp;hellip; This is where things went south.&lt;/p&gt;
&lt;p&gt;As I started integrating various endpoints, I discovered many problems with the backend API design. It was flawed. I patiently worked with the backend developer to amend these flaws, and trying to integrate whatever I can with the app itself. At that time, the transition between Xcode 6 and 7 happened, as well as my discovery that &lt;a href="https://mazyod.com/blog/2015/09/09/welcome-to-realm/"&gt;CoreData and Swift don&amp;rsquo;t work well with each other&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Progress wasn&amp;rsquo;t being made as fast as it started thanks to these problems, and then out of nowhere, the client got worried and discouraged. I tried to explain how the problems affecting development were slowing the progress, but due to severe lack of communication, the client just made up theories about this project, and decided to end the contract.&lt;/p&gt;
&lt;p&gt;This was the best possible outcome for me, I was starting to hate the project, but still. I had worked hard to put this together and didn&amp;rsquo;t like it ending that way. So, I started thinking back, where did it all go wrong?&lt;/p&gt;
&lt;p&gt;It was the negotiation phase. If the client knew a little bit about the issues I was going through, they would&amp;rsquo;ve appreciated the effort put into making this app happen. I guess trust plays part, as well. The client didn&amp;rsquo;t trust anyone, and even complained about the designer not doing his job&amp;hellip; It was only a matter of time I would run into this issue, and I did.&lt;/p&gt;
&lt;h3&gt;Lesson 2: Price&lt;/h3&gt;
&lt;p&gt;Whatever you do, never work for a fixed price. &lt;strong&gt;&lt;em&gt;Never&lt;/em&gt;&lt;/strong&gt;. No exceptions.&lt;/p&gt;
&lt;p&gt;There are literally zero clients that will come to you and say &amp;ldquo;Hey, my project is complicated, and I appreciate any effort you put in&amp;rdquo;. Instead, all their projects are &amp;ldquo;simple&amp;rdquo; and &amp;ldquo;straight-forward&amp;rdquo;, should be done in less then a few months, and they have all the details figured out&amp;hellip; You&amp;rsquo;re looking at the wireframes going, &amp;ldquo;Yeah&amp;hellip; that&amp;rsquo;s a scribble on a napkin, what am I suppose to make out of that?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/software_development_comic.jpg"&gt;&lt;/p&gt;
&lt;p&gt;The solution to that is actually quite simple. Don&amp;rsquo;t work for fixed price, ever. For your sake and the sake of the client, working for fixed price means one will be cheating the other. It&amp;rsquo;ll either be the developer doing a crappy job and demanding the whole pay, or the client making unreasonable claims about the scope as they envisioned it, demanding you see it through (even if it takes years). Really, you don&amp;rsquo;t want that.&lt;/p&gt;
&lt;p&gt;If you are paid an hourly rate, it no longer matters how things turn out. If you are are not holding up your end of the bargain, your payment is cut. If the client wants to keep making demands, they have to start shaking them pockets. It&amp;rsquo;s simply the most fair setup I found.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Well, look at that! Just discussing the negotiation part took so much to cover, and yet more parts are to be discussed! I&amp;rsquo;ll leave this here for now, but will hopefully post more on this topic later.&lt;/p&gt;</content><category term="posts"></category><category term="freelancing"></category><category term="programming"></category><category term="career"></category><category term="contract"></category><category term="toptal"></category><category term="client"></category><category term="ios"></category><category term="communication"></category><category term="project"></category><category term="management"></category></entry><entry><title>iOS or Android Remote Logging</title><link href="https://mazyod.com/blog/2015/11/30/ios-or-android-remote-logging/" rel="alternate"></link><published>2015-11-30T22:42:15+00:00</published><updated>2015-11-30T22:42:15+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-30:/blog/2015/11/30/ios-or-android-remote-logging/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I have highlighted &lt;a href="https://mazyod.com/blog/2015/11/27/lavish-ideas/"&gt;in a previous post&lt;/a&gt; that I&amp;rsquo;ll be writing a topic about &lt;a href="https://getsentry.com/welcome/"&gt;Sentry&lt;/a&gt;. The reason I said that was because I was in the process of building a remote logging service for an iOS app. Ultimately, it took less than two hours to implement.&lt;/p&gt;
&lt;p&gt;Here is …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I have highlighted &lt;a href="https://mazyod.com/blog/2015/11/27/lavish-ideas/"&gt;in a previous post&lt;/a&gt; that I&amp;rsquo;ll be writing a topic about &lt;a href="https://getsentry.com/welcome/"&gt;Sentry&lt;/a&gt;. The reason I said that was because I was in the process of building a remote logging service for an iOS app. Ultimately, it took less than two hours to implement.&lt;/p&gt;
&lt;p&gt;Here is the scoop: Sentry is just impossible to deploy for a n00b like me. It is dependent on nginx, django, redis, and postgres&amp;hellip; Can you believe that? I just want to get a logging server for a simple app, and I have to learn and deploy all these services? I didn&amp;rsquo;t have the luxury of time, so a pivot was inevitable.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.firebase.com/"&gt;Firebase&lt;/a&gt; came to the rescue. I was able to read their docs, learn how it worked, design and implement the remote logger in the iOS app, all in less then 2 hours. That&amp;rsquo;s how great Firebase is.&lt;/p&gt;
&lt;h2&gt;Business Needs&lt;/h2&gt;
&lt;p&gt;First off, let me shed some light on the situation here&amp;hellip;&lt;/p&gt;
&lt;p&gt;The App we are talking about is a B2B native iOS/Android application. It is deployed to a handful of businesses in order to streamline a certain activity of theirs. That&amp;rsquo;s it, let&amp;rsquo;s try to break this paragraph into requirements.&lt;/p&gt;
&lt;p&gt;The fact that the application is B2B puts it at a whole other level than regular B2C apps. B2B implies higher standards, less error tolerance, and extremely high support expectancy. If the app crashes while they&amp;rsquo;re using it, they expect you to be on top of it ASAP, with little intervention from their side.&lt;/p&gt;
&lt;p&gt;Then, there is the fact that we have native apps out there. That puts us at a disadvantage in terms of reachability and maintainability, since it&amp;rsquo;s almost impossible to quickly and accurately monitor user activity and provide support in real-time, like web apps do&amp;hellip; But, we can actually address that.&lt;/p&gt;
&lt;p&gt;Finally, we are only deploying to a handful of businesses. This eliminates the need of complex data arrangements and needs. For now, it&amp;rsquo;s important to me mean and lean!&lt;/p&gt;
&lt;h2&gt;Detailed Monitoring&lt;/h2&gt;
&lt;p&gt;The problem we would like to address today is: Monitoring.&lt;/p&gt;
&lt;p&gt;After submitting the application to the AppStore, and our users downloading the apps, we would like to quickly find problems and be alerted, if any, before the users even reach out to us. This will help our company&amp;rsquo;s image in being professional and on top of problems, as previously highlighted.&lt;/p&gt;
&lt;p&gt;The parameters needed to make sure this works are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The User&lt;/li&gt;
&lt;li&gt;Log Type&lt;/li&gt;
&lt;li&gt;Some Info&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We really need to log events per user, have distinct log types in order to filter out the trace logs from the actual errors, and finally some info associated with these logs in order to figure out what is happening!&lt;/p&gt;
&lt;h2&gt;Firebase Logger&lt;/h2&gt;
&lt;p&gt;That is how Firebase Logger was born. I apologize in advance for the crappy Obj-C code, but this is an old project:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cm"&gt;/** A simple logger that sends all the logs to firebase&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="k"&gt;@interface&lt;/span&gt; &lt;span class="nc"&gt;NSHFirebaseLogger&lt;/span&gt; : &lt;span class="bp"&gt;NSObject&lt;/span&gt;

&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;logSuccess:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&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="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;logInfo:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&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="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;logWarn:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&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="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;logFail:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;...;&lt;/span&gt;

&lt;span class="k"&gt;@end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The interface of the logger is nothing exciting at all.. It simply takes in a message format with arguments to construct the actual log message for a certain log level. The actual log method is where things get interesting&amp;hellip;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;_log:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;LogLevel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;format:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;args:&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;va_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nv"&gt;args&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;alloc&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;initWithFormat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;arguments&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;NSString&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;stringWithFormat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@&amp;quot;[%@]: %@&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LogLevelLabel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The beginning of the method, we simply want to build the full log message, including the log level. So the code above simply spits our something like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[WARN]: User decided to actually press the delete all data button&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Firebase&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="bp"&gt;NSDictionary&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;deviceInfo&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;NSDictionary&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;deviceDetailsForLogin&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;NSHUser&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;NSHAppManager&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;sharedManager&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;loggedInUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now it gets interesting&amp;hellip; We first prepare a &lt;code&gt;Firebase&lt;/code&gt; reference, we will see what that will do later on. Then, we use a convenient &lt;code&gt;NSDictionary&lt;/code&gt; call to get the device info, like the device model, MAC address, &amp;hellip; etc. Finally, we try to query for the logged in user from the account manager class.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firebaseRoot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;childByAppendingPath&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;firebaseRoot&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;childByAppendingPath&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;deviceInfo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DeviceIdKey&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;About the user, if there is a user logged in, we want the firebase log tree to start with that user&amp;rsquo;s username. If that is not possible, then use the device ID, which we log in the backend anyway, as the root of the logs.&lt;/p&gt;
&lt;p&gt;As you can see here, &lt;code&gt;Firebase&lt;/code&gt; is a simple and elegant object that is like a key value &amp;ldquo;tree&amp;rdquo;. Keys and values can be nested in a tree manner, as we will see in the end. So, taking the root &lt;code&gt;Firebase&lt;/code&gt; object, we start to build the tree by creating a child using the &lt;code&gt;appendPath&lt;/code&gt; method.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;childByAppendingPath&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;deviceInfo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;DeviceModelKey&lt;/span&gt;&lt;span class="p"&gt;]];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;childByAppendingPath&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="s"&gt;@&amp;quot;logs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;childByAutoId&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, we simply continue building this tree by adding 3 more children. The first is the device model, just in case the user has multiple phones. I figured it&amp;rsquo;s quite rare for a user to have two devices of the same model, so this should be ok.&lt;/p&gt;
&lt;p&gt;Then, we add a hard-coded &amp;ldquo;logs&amp;rdquo; node to contain the keys for all the logs. We do that by immediately adding the &lt;code&gt;childByAutoId&lt;/code&gt;, which simply creates a unique id for the log we are storing, right under &amp;ldquo;logs&amp;rdquo;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;firebaseLogs&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;setValue&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;NSLog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;XCODE_COLORS_ESCAPE&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;@&amp;quot;%@ %@ &amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;XCODE_COLORS_RESET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LogLevelColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;log&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;Finally, we assign the value of this node that we reached to the log message. We also print the log to the console for debugging purposes. I should probably wrap it with &lt;code&gt;#if DEBUG&lt;/code&gt;, though.&lt;/p&gt;
&lt;p&gt;Now, let&amp;rsquo;s see what this handy work of ours gives us:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/firebase-nashr.png"&gt;&lt;/p&gt;
&lt;p&gt;Isn&amp;rsquo;t that just dandy! This is the default firebase web viewer, and you can see how neatly the logs are structured, and how easy it is to quickly dig into them and find issues for a particular user.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The best part is, it doesn&amp;rsquo;t have to stop there! Adding a cron job to process the logs and give alerts or whatnot wouldn&amp;rsquo;t be a bad idea. Also, it could provide a better log reading experience. The point is, the base is taken care of by Firebase, you just have to use your imagination from hereon onwards.&lt;/p&gt;</content><category term="posts"></category><category term="software"></category><category term="development"></category><category term="mobile"></category><category term="ios"></category><category term="android"></category><category term="firebase"></category><category term="logging"></category><category term="remote"></category><category term="bugs"></category><category term="debugging"></category><category term="tracking"></category><category term="b2b"></category><category term="lean"></category><category term="startup"></category></entry><entry><title>Oh My Zsh!</title><link href="https://mazyod.com/blog/2015/11/28/oh-my-zsh/" rel="alternate"></link><published>2015-11-28T15:18:38+00:00</published><updated>2015-11-28T15:18:38+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-28:/blog/2015/11/28/oh-my-zsh/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Hardly any developer can go about his career without interacting with the terminal on daily basis. Many tools continue to be developed as command line apps, like &lt;a href="http://fastlane.tools"&gt;fastlane&lt;/a&gt;, &lt;a href="https://jekyllrb.com"&gt;Jekyll&lt;/a&gt;, and many more &amp;hellip; With all that being said, we need to make terminal more usable!&lt;/p&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been ssh-ing …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Hardly any developer can go about his career without interacting with the terminal on daily basis. Many tools continue to be developed as command line apps, like &lt;a href="http://fastlane.tools"&gt;fastlane&lt;/a&gt;, &lt;a href="https://jekyllrb.com"&gt;Jekyll&lt;/a&gt;, and many more &amp;hellip; With all that being said, we need to make terminal more usable!&lt;/p&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been ssh-ing into an Ubuntu server that defaults to bash, and I quickly realized how my terminal life has been completely turned around thanks to &lt;a href="http://zsh.org"&gt;zsh&lt;/a&gt;. Here are a few examples of why it is just pure awesomeness.&lt;/p&gt;
&lt;p&gt;Before I begin, let me just say that I have immediately installed &lt;a href="http://ohmyz.sh/"&gt;Oh My ZSH&lt;/a&gt; right after installing zsh itself, so I am not sure which features are specific to zsh and which are added by the plug-in.&lt;/p&gt;
&lt;h2&gt;Z Shell&lt;/h2&gt;
&lt;p&gt;When mentioning the features, I guess I&amp;rsquo;ll sort them in terms of the most important to me, down to the most &amp;ldquo;meh&amp;rdquo;. It&amp;rsquo;s purely subjective, but here we go:&lt;/p&gt;
&lt;h3&gt;Timelapse&lt;/h3&gt;
&lt;p&gt;I can&amp;rsquo;t get enough of this feature. You simply type a command, then hit the up arrow key, and BAM! You are cycling through your history &lt;strong&gt;of that specific command&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;ssh-add&lt;span class="w"&gt; &lt;/span&gt;↑
%&lt;span class="w"&gt; &lt;/span&gt;ssh-add&lt;span class="w"&gt; &lt;/span&gt;~/.ssh/github-terminal
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This feature saved me countless (accumulated) hours. From running &lt;code&gt;py.test&lt;/code&gt;, adding ssh keys, all the way to simply removing Xcode&amp;rsquo;s derived data folder:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;↑
%&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;-Rf&lt;span class="w"&gt; &lt;/span&gt;/Users/mazyod/Library/Developer/Xcode/DerivedData
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It is by far my best feature, but the rest of the features are pretty kickass as well.&lt;/p&gt;
&lt;h3&gt;Cycling&lt;/h3&gt;
&lt;p&gt;If you are a lazy typer like me, then you&amp;rsquo;d feel for me when I say that nothing is more annoying than bash continuously blocking [Tab] completion because many completions exist!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$&lt;span class="w"&gt; &lt;/span&gt;ss⇥
SSH_AUTH_SOCK&lt;span class="w"&gt;  &lt;/span&gt;ssh-keygen&lt;span class="w"&gt;   &lt;/span&gt;
ssh&lt;span class="w"&gt;            &lt;/span&gt;ssh-keyscan&lt;span class="w"&gt;  &lt;/span&gt;
ssh-add&lt;span class="w"&gt;        &lt;/span&gt;sshd&lt;span class="w"&gt;         &lt;/span&gt;
ssh-agent&lt;span class="w"&gt;      &lt;/span&gt;sso_util
$&lt;span class="w"&gt; &lt;/span&gt;ssh-⇥
ssh-add&lt;span class="w"&gt;      &lt;/span&gt;ssh-keygen
ssh-agent&lt;span class="w"&gt;    &lt;/span&gt;ssh-keyscan
$&lt;span class="w"&gt; &lt;/span&gt;ssh-a⇥
ssh-add&lt;span class="w"&gt;    &lt;/span&gt;ssh-agent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Annoying!!! How does zsh solve that? Well, if you hit &lt;strong&gt;double tab&lt;/strong&gt;, it shows a selection highlight, so you can cycle through the options and choose the command you like!&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/zsh-cycling.png"&gt;&lt;/p&gt;
&lt;p&gt;This is just so convenient&amp;hellip;&lt;/p&gt;
&lt;h3&gt;Auto-Correction&lt;/h3&gt;
&lt;p&gt;Once you start typing a command then hit Tab, it can correct your typo automatically, and does so in many ways!&lt;/p&gt;
&lt;h4&gt;CUSTOM AUTO COMPLETION&lt;/h4&gt;
&lt;p&gt;With the right plug-ins from oh my zsh, you can have custom auto completion for your favorite commands! Let&amp;rsquo;s see &lt;code&gt;git&lt;/code&gt; for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;git⇥
add&lt;span class="w"&gt;       &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;add&lt;span class="w"&gt; &lt;/span&gt;file&lt;span class="w"&gt; &lt;/span&gt;contents&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;index
bisect&lt;span class="w"&gt;    &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;find&lt;span class="w"&gt; &lt;/span&gt;by&lt;span class="w"&gt; &lt;/span&gt;binary&lt;span class="w"&gt; &lt;/span&gt;search&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;change&lt;span class="w"&gt; &lt;/span&gt;that&lt;span class="w"&gt; &lt;/span&gt;introduced&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;bug
branch&lt;span class="w"&gt;    &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;list,&lt;span class="w"&gt; &lt;/span&gt;create,&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;delete&lt;span class="w"&gt; &lt;/span&gt;branches
checkout&lt;span class="w"&gt;  &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;checkout&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;branch&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;paths&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;working&lt;span class="w"&gt; &lt;/span&gt;tree
clone&lt;span class="w"&gt;     &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;clone&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;repository&lt;span class="w"&gt; &lt;/span&gt;into&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;new&lt;span class="w"&gt; &lt;/span&gt;directory
commit&lt;span class="w"&gt;    &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;record&lt;span class="w"&gt; &lt;/span&gt;changes&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;repository
diff&lt;span class="w"&gt;      &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;changes&lt;span class="w"&gt; &lt;/span&gt;between&lt;span class="w"&gt; &lt;/span&gt;commits,&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;working&lt;span class="w"&gt; &lt;/span&gt;tree,&lt;span class="w"&gt; &lt;/span&gt;etc
fetch&lt;span class="w"&gt;     &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;download&lt;span class="w"&gt; &lt;/span&gt;objects&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;refs&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;another&lt;span class="w"&gt; &lt;/span&gt;repository
grep&lt;span class="w"&gt;      &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;print&lt;span class="w"&gt; &lt;/span&gt;lines&lt;span class="w"&gt; &lt;/span&gt;matching&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;pattern
init&lt;span class="w"&gt;      &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;create&lt;span class="w"&gt; &lt;/span&gt;an&lt;span class="w"&gt; &lt;/span&gt;empty&lt;span class="w"&gt; &lt;/span&gt;Git&lt;span class="w"&gt; &lt;/span&gt;repository&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;reinitialize&lt;span class="w"&gt; &lt;/span&gt;an&lt;span class="w"&gt; &lt;/span&gt;existing&lt;span class="w"&gt; &lt;/span&gt;one
log&lt;span class="w"&gt;       &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;commit&lt;span class="w"&gt; &lt;/span&gt;logs
merge&lt;span class="w"&gt;     &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;join&lt;span class="w"&gt; &lt;/span&gt;two&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;more&lt;span class="w"&gt; &lt;/span&gt;development&lt;span class="w"&gt; &lt;/span&gt;histories&lt;span class="w"&gt; &lt;/span&gt;together
mv&lt;span class="w"&gt;        &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;move&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;rename&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;file,&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;directory,&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;symlink
pull&lt;span class="w"&gt;      &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;fetch&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;merge&lt;span class="w"&gt; &lt;/span&gt;with&lt;span class="w"&gt; &lt;/span&gt;another&lt;span class="w"&gt; &lt;/span&gt;repository&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;branch
push&lt;span class="w"&gt;      &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;update&lt;span class="w"&gt; &lt;/span&gt;remote&lt;span class="w"&gt; &lt;/span&gt;refs&lt;span class="w"&gt; &lt;/span&gt;along&lt;span class="w"&gt; &lt;/span&gt;with&lt;span class="w"&gt; &lt;/span&gt;associated&lt;span class="w"&gt; &lt;/span&gt;objects
rebase&lt;span class="w"&gt;    &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;forward-port&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;commits&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;updated&lt;span class="w"&gt; &lt;/span&gt;upstream&lt;span class="w"&gt; &lt;/span&gt;head
reset&lt;span class="w"&gt;     &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;reset&lt;span class="w"&gt; &lt;/span&gt;current&lt;span class="w"&gt; &lt;/span&gt;HEAD&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;specified&lt;span class="w"&gt; &lt;/span&gt;state
rm&lt;span class="w"&gt;        &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;remove&lt;span class="w"&gt; &lt;/span&gt;files&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;working&lt;span class="w"&gt; &lt;/span&gt;tree&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;from&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;index
show&lt;span class="w"&gt;      &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;various&lt;span class="w"&gt; &lt;/span&gt;types&lt;span class="w"&gt; &lt;/span&gt;of&lt;span class="w"&gt; &lt;/span&gt;objects
status&lt;span class="w"&gt;    &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;show&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;working&lt;span class="w"&gt; &lt;/span&gt;tree&lt;span class="w"&gt; &lt;/span&gt;status
tag&lt;span class="w"&gt;       &lt;/span&gt;--&lt;span class="w"&gt; &lt;/span&gt;create,&lt;span class="w"&gt; &lt;/span&gt;list,&lt;span class="w"&gt; &lt;/span&gt;delete&lt;span class="w"&gt; &lt;/span&gt;or&lt;span class="w"&gt; &lt;/span&gt;verify&lt;span class="w"&gt; &lt;/span&gt;a&lt;span class="w"&gt; &lt;/span&gt;tag&lt;span class="w"&gt; &lt;/span&gt;object&lt;span class="w"&gt; &lt;/span&gt;signed&lt;span class="w"&gt; &lt;/span&gt;with&lt;span class="w"&gt; &lt;/span&gt;GPG
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;WRONG COMMAND&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;xcodeguild
zsh:&lt;span class="w"&gt; &lt;/span&gt;correct&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;xcodeguild&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;xcodebuild&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;nyae&lt;span class="o"&gt;]&lt;/span&gt;?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Not only does it correct it for you, but also allows you to hit &lt;code&gt;e&lt;/code&gt; and edit the command, just in case it didn&amp;rsquo;t get it right.&lt;/p&gt;
&lt;h4&gt;MIND READER&lt;/h4&gt;
&lt;p&gt;zsh ships with a mind reader, really! Look:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;ls
blog&lt;span class="w"&gt;          &lt;/span&gt;untiy3d-game&lt;span class="w"&gt;  &lt;/span&gt;upcoming-book
%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;game⇥
%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;untiy3d-game/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;I DoNt cArE&lt;/h4&gt;
&lt;p&gt;As a final note, zsh doesn&amp;rsquo;t torture you for not getting the CAPS right. It will happily accept wrong caps for files, and correct that for you.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;doCuMent⇥
%&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;Documents/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;ZMV&lt;/h3&gt;
&lt;p&gt;I am not sure where this command comes from, but it is just super for renaming files. All you have to do is autoload it, and then use it. For example, let&amp;rsquo;s say we have a bunch of png images we want to append &lt;code&gt;@2x&lt;/code&gt; to the end, before the extension:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;autoload&lt;span class="w"&gt; &lt;/span&gt;-U&lt;span class="w"&gt; &lt;/span&gt;zmv
%&lt;span class="w"&gt; &lt;/span&gt;zmv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(*).png&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;$1@2x.png&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is not all &amp;hellip; If the rename will mess up your files by overwriting each other, it will detect that and abort the whole operation, leaving your files intact! In case you didn&amp;rsquo;t understand, let&amp;rsquo;s see the following example.&lt;/p&gt;
&lt;p&gt;Here, I inaptly tried to rename all the images in an Xcode catalog tree to &amp;ldquo;oops.png&amp;rdquo; in the root directory. Normally, this command would mean I lose all the images, and only get a single image &amp;ldquo;oops.png&amp;rdquo;, corresponding the the last image the command runs on. Not zmv. It gave me a readable error, and aborted the operation. I checked git, nothing changed at all!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt;⚡&lt;span class="w"&gt; &lt;/span&gt;%&lt;span class="w"&gt; &lt;/span&gt;zmv&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;(*)/(*).png&amp;#39;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;oops.png&amp;#39;&lt;/span&gt;
zmv:&lt;span class="w"&gt; &lt;/span&gt;error&lt;span class="o"&gt;(&lt;/span&gt;s&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;substitution:
button.imageset/button@2x.png&lt;span class="w"&gt; &lt;/span&gt;and&lt;span class="w"&gt; &lt;/span&gt;button.imageset/button.png&lt;span class="w"&gt; &lt;/span&gt;both&lt;span class="w"&gt; &lt;/span&gt;map&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;oops.png
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Themes&lt;/h3&gt;
&lt;p&gt;YES! Zsh allows you to install custom themes shared by other awesome people, and the choices are just too good. So many different themes, it&amp;rsquo;s hard not to find what you are aiming for.&lt;/p&gt;
&lt;p&gt;My choice was tricky, yet I still found the exact theme I wanted. I need something that shows the cwd on the right, the colors to be according to &lt;a href="http://color.smyck.org/"&gt;SMYCK color scheme&lt;/a&gt;, displays the active git branch, and nothing else. It must be minimal .. and I found it, the wezm theme:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;ZSH_THEME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;wezm&amp;quot;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;# norm also good&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;img alt="image" src="/images/zsh-theme.png"&gt;&lt;/p&gt;
&lt;h3&gt;Misc&lt;/h3&gt;
&lt;p&gt;Here is a dump of more features that collectively make terminal a hell lot more usable.&lt;/p&gt;
&lt;h4&gt;NUKE CONFIRMATION&lt;/h4&gt;
&lt;p&gt;I am not worried about typing &lt;code&gt;sudo rm -Rf *&lt;/code&gt; anymore.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;%&lt;span class="w"&gt; &lt;/span&gt;rm&lt;span class="w"&gt; &lt;/span&gt;-Rf&lt;span class="w"&gt; &lt;/span&gt;*
zsh:&lt;span class="w"&gt; &lt;/span&gt;sure&lt;span class="w"&gt; &lt;/span&gt;you&lt;span class="w"&gt; &lt;/span&gt;want&lt;span class="w"&gt; &lt;/span&gt;to&lt;span class="w"&gt; &lt;/span&gt;delete&lt;span class="w"&gt; &lt;/span&gt;all&lt;span class="w"&gt; &lt;/span&gt;the&lt;span class="w"&gt; &lt;/span&gt;files&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;/Users/mazyod&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;yn&lt;span class="o"&gt;]&lt;/span&gt;?
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="posts"></category><category term="terminal"></category><category term="zsh"></category><category term="scripting"></category><category term="console"></category><category term="productivity"></category><category term="tools"></category><category term="cli"></category><category term="command-line"></category><category term="bash"></category></entry><entry><title>Lavish Ideas</title><link href="https://mazyod.com/blog/2015/11/27/lavish-ideas/" rel="alternate"></link><published>2015-11-27T00:33:33+00:00</published><updated>2015-11-27T00:33:33+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-27:/blog/2015/11/27/lavish-ideas/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;While thinking for a topic to write about, I realized that just the fact of choosing a topic is a whole post in itself! Recently, I&amp;rsquo;ve been discovering cool new technologies, and I just can&amp;rsquo;t wait to write about them .. I&amp;rsquo;ll post them here for remembering …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;While thinking for a topic to write about, I realized that just the fact of choosing a topic is a whole post in itself! Recently, I&amp;rsquo;ve been discovering cool new technologies, and I just can&amp;rsquo;t wait to write about them .. I&amp;rsquo;ll post them here for remembering that later.&lt;/p&gt;
&lt;h2&gt;Ideas Are Dime a Dozen&lt;/h2&gt;
&lt;h3&gt;Sentry + iOS&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve been integrating &lt;a href="https://getsentry.com/welcome/"&gt;Sentry&lt;/a&gt; with an iOS app these days, and it&amp;rsquo;s a really rewarding experience. I&amp;rsquo;ve assumed charge of the whole stack, from deploying Sentry on &lt;a href="http://aws.amazon.com/free"&gt;AWS&lt;/a&gt;, all the way to writing the exact logs in the iOS app itself. Will hopefully post about that as soon as its done!&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mazyod.com/blog/2015/11/30/ios-or-android-remote-logging/"&gt;Post published!&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;AppleTV&lt;/h3&gt;
&lt;p&gt;Another thing is developing an Apple TV app from an existing iOS app source. AppleTV SDK is pretty good, but there are some really nice (and really weird) differences. I&amp;rsquo;ll hopefully highlight that experience once it is done, as well.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mazyod.com/blog/2015/12/10/developing-tvos-apps/"&gt;Post published!&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;zsh&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://www.zsh.org/"&gt;zsh&lt;/a&gt; is just just simply the best thing that happened to my terminal experience hands down. In terms of overall benefit to my workflow, it easily out-shines Homebrew, cask, and any other tool I&amp;rsquo;ve ever used .. COMBINED. I just have to write about how awesome zsh is .. In fact, I&amp;rsquo;ll start drafting this post right now, and just fill it up as I keep using zsh everyday.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mazyod.com/blog/2015/11/28/oh-my-zsh/"&gt;Post published!&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;On Being a Freelancer&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve worked on two freelance projects in the past few months, and I believe there are some really good lessons I&amp;rsquo;ve learned that could be worth sharing. It&amp;rsquo;s unfortunate that freelancing isn&amp;rsquo;t what we imagine it to be&amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mazyod.com/blog/2015/12/02/freelancing-stories/"&gt;Post published!&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;WatchOS Apps&lt;/h3&gt;
&lt;p&gt;Of course! I&amp;rsquo;ve recently shipped an app with AppleWatch support, including glances, complications, and time travel! Definitely interesting topics to be discussed on that front.&lt;/p&gt;
&lt;h3&gt;Kitz&lt;/h3&gt;
&lt;p&gt;As I build more bits and pieces of &lt;a href="http://kitz.io/"&gt;Kitz&lt;/a&gt;, I keep learning more and more important lessons I&amp;rsquo;d really like to discuss in depth on this blog. &lt;a href="https://mazyod.com/blog/2015/11/20/generic-constraints-with-optionals/"&gt;I&amp;rsquo;ve already posted about one&lt;/a&gt;, but there is way more stuff to be posted.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://mazyod.com/blog/2015/12/07/swifty-nsnotificationcenter/"&gt;Post published!&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Software development is just a single field in a whole ocean of knowledge, and yet it is an ocean itself in its enormity&amp;hellip; May be overwhelming at times, but if you imagine it as some sort of RPG, it&amp;rsquo;s always exciting to go about discovering new dungeons! Always more fun with a party, as well!&lt;/p&gt;</content><category term="posts"></category><category term="blog"></category><category term="rant"></category><category term="life"></category><category term="choices"></category><category term="tech"></category></entry><entry><title>Hacking With Jekyll</title><link href="https://mazyod.com/blog/2015/11/25/hacking-with-jekyll/" rel="alternate"></link><published>2015-11-25T18:03:49+00:00</published><updated>2015-11-25T18:03:49+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-25:/blog/2015/11/25/hacking-with-jekyll/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;For those of you who are new here, welcome! For the rest of the old time readers, yeah, the blog has been completely redesigned .. From scratch. I hope the new design is a step forward at least, and in this post, I&amp;rsquo;ll be covering the transition experience.&lt;/p&gt;
&lt;h2&gt;Where …&lt;/h2&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;For those of you who are new here, welcome! For the rest of the old time readers, yeah, the blog has been completely redesigned .. From scratch. I hope the new design is a step forward at least, and in this post, I&amp;rsquo;ll be covering the transition experience.&lt;/p&gt;
&lt;h2&gt;Where Were We?&lt;/h2&gt;
&lt;p&gt;The previous blog was built on top of &lt;a href="http://octopress.org/"&gt;Octopress&lt;/a&gt; and using a &lt;a href="https://github.com/Mazyod/octoflat"&gt;heavily modified&lt;/a&gt; &lt;a href="https://github.com/alexgaribay/octoflat"&gt;octoflat theme&lt;/a&gt;. That is to try and say &amp;hellip; It was ultra-bloated.&lt;/p&gt;
&lt;h3&gt;Octopress&lt;/h3&gt;
&lt;p&gt;Octopress was amazing .. As long as it was actually working. It had many convenient wrappers around Jekyll, uses Ruby &lt;code&gt;rake&lt;/code&gt; to do stuff, and wasn&amp;rsquo;t so bad all things considered. The only problem was, it was complicated.&lt;/p&gt;
&lt;p&gt;Octopress was using Jekyll plugins to its fullest. Also, I was using it pre-v3.0, so it was tightly integrated with git. That made upgrading octopress an unpleasant chore.&lt;/p&gt;
&lt;p&gt;Most annoying crap I dealt with was &lt;a href="http://compass-style.org/"&gt;compass&lt;/a&gt;. It just didn&amp;rsquo;t work most of the time, hard to configure, and full of bugs. Thankfully, it&amp;rsquo;s removed in most recent octopress releases.&lt;/p&gt;
&lt;p&gt;Another pain point was generating the blog from source &amp;hellip; Since I was using lots of plugins, I couldn&amp;rsquo;t make github generate the website for me, so I had to build it locally, then push the result. Generating the blog took about 10 - 15 mins! That was crazy .. I know I have 200+ posts, but still! This was really annoying, especially if I had made some sort of syntax error or want to preview a post.&lt;/p&gt;
&lt;p&gt;Finally, the elaborate directory structure and options were overwhelming for my needs, hence it was time to be minimalistic.&lt;/p&gt;
&lt;h3&gt;Octoflat&lt;/h3&gt;
&lt;p&gt;I shouldn&amp;rsquo;t talk about this .. Countless times I get hollered at by &lt;a href="https://twitter.com/jimmarxd"&gt;Jim&lt;/a&gt; because something broke, like pagination or image size on Android. Even more annoying was tweaking the design a bit, and watching all hell break loose. It is just a very bloated theme for my simple needs. How not when it includes bootstrap, flat-ui, and a million other styles, all mushed together. The &lt;code&gt;!important&lt;/code&gt; tags were countless, lol.&lt;/p&gt;
&lt;p&gt;All things considered, I really appreciate the author&amp;rsquo;s efforts in open sourcing it. It served me well these past few years.&lt;/p&gt;
&lt;h3&gt;Experience&lt;/h3&gt;
&lt;p&gt;I noticed that the reader feature on iPhone wasn&amp;rsquo;t available, which is a huge missing feature for readers. Another problem was the overall design of the blog. I hadn&amp;rsquo;t thoroughly thought about UX back then, so colors, fonts, layouts were all just a huge letdown.&lt;/p&gt;
&lt;h2&gt;Where Are We?&lt;/h2&gt;
&lt;p&gt;The new blog is so simple, I don&amp;rsquo;t even have to break it down into sections. It&amp;rsquo;s a pure Jekyll powered blog with minimal changes on the default theme. Yup, all I did was tweak the default theme a bit to achieve the current look, without adding a single dependency or framework.&lt;/p&gt;
&lt;p&gt;The blog finally generates in just &lt;em&gt;7 seconds&lt;/em&gt;, compared to the original 15 minutes, I&amp;rsquo;d say that&amp;rsquo;s a significant win. Also, all I have to do is push the changes to github, and github will build the blog for me! Yatta!&lt;/p&gt;
&lt;p&gt;Admittedly, I had to &lt;a href="https://mazyod.com/blog/2014/03/16/blogging-with-octopress/"&gt;rewrite all the script I had&lt;/a&gt;, but that&amp;rsquo;s ok! Now that I have full control over the template created for a new post, I went ahead and created a much more sensible default template for my needs. All it took was a couple of minutes, really. I&amp;rsquo;ll probably blog about the new workflow some day!&lt;/p&gt;
&lt;p&gt;Last but not least, now I have the capacity to maybe do A/B testing, see which changes readers like more and so on, since making changes is so easy!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I am in love with &lt;a href="http://www.zsh.org/"&gt;zsh&lt;/a&gt;. &lt;a href="http://genius.com/2448969"&gt;Seriously, if you&amp;rsquo;re not on that thing, you&amp;rsquo;re missing out, because this shit is thoroughly good&lt;/a&gt;!&lt;/p&gt;</content><category term="posts"></category><category term="blog"></category><category term="jekyll"></category><category term="octopress"></category><category term="markdown"></category><category term="python"></category><category term="scripting"></category><category term="ruby"></category><category term="github"></category><category term="pages"></category><category term="post"></category><category term="entry"></category></entry><entry><title>One More Time</title><link href="https://mazyod.com/blog/2015/11/23/one-more-time/" rel="alternate"></link><published>2015-11-23T16:08:12+00:00</published><updated>2015-11-23T16:08:12+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-23:/blog/2015/11/23/one-more-time/</id><content type="html">&lt;p&gt;No introduction, no conclusion, just pure anticipation of the new blog design to be rolled out. Yes, the blog shall be redesigned and relaunched one more time. I am spending my free time on the redesign rather than blogging, so here is something to generate some hype:&lt;/p&gt;
&lt;h3&gt;Coming soon&lt;/h3&gt;
&lt;p&gt;&lt;img alt="image" src="/images/blog-content-design.png"&gt;&lt;/p&gt;</content><category term="posts"></category><category term="rant"></category><category term="design"></category><category term="ui"></category><category term="ux"></category><category term="blog"></category><category term="snippet"></category><category term="life"></category></entry><entry><title>Wrangling Autolayout</title><link href="https://mazyod.com/blog/2015/11/21/wrangling-autolayout/" rel="alternate"></link><published>2015-11-21T20:30:58+00:00</published><updated>2015-11-21T20:30:58+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-21:/blog/2015/11/21/wrangling-autolayout/</id><summary type="html">&lt;h2&gt;Autolayout Ambiguity&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d like to share today a short story about autolayout. Before I get into that, however, I&amp;rsquo;d like to give some background regarding my experience with autolayout for the sake of helping you better relate to the upcoming story.&lt;/p&gt;
&lt;p&gt;Auto-layout was just an unusable nuisance for …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Autolayout Ambiguity&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d like to share today a short story about autolayout. Before I get into that, however, I&amp;rsquo;d like to give some background regarding my experience with autolayout for the sake of helping you better relate to the upcoming story.&lt;/p&gt;
&lt;p&gt;Auto-layout was just an unusable nuisance for me when it came out on Xcode 4 for iOS. The first step after creating any XIB file was to turn it off. It&amp;rsquo;s not like I didn&amp;rsquo;t try it .. I did, but back then, Xcode would crash, layout would easily mess up your views, &amp;hellip; etc.&lt;/p&gt;
&lt;p&gt;As I progressed in my career, I came across an use case that inevitably has to use autolayout (unless I want to lose my mind). That use case was Right-to-Left (RTL) support for the Telly app. In order to properly support RTL layout without writing a million tedious layout code everywhere, I had to use autolayout with its automatic layout correction. Luckily, that worked really well, since the views I needed to add support to were &lt;strong&gt;all&lt;/strong&gt; properly broken down and created in XIB files. enabling autolayout and setting things up was child&amp;rsquo;s play.&lt;/p&gt;
&lt;p&gt;Those days are over now, and I&amp;rsquo;ve recently started doing some fresh projects and experimenting with Storyboards, Segues, and more Autolayout. Here is the weird part: I&amp;rsquo;ve built two apps that started with Storyboards and Autolayout, and ended up deleting them and using manual layout (&lt;code&gt;layoutSubviews()&lt;/code&gt;)! Why?&lt;/p&gt;
&lt;p&gt;I simply didn&amp;rsquo;t have enough time to step back and see exactly where my layout was breaking. I remember quickly running into problems and quickly switched to something I am proficient at, manual frame calculation&amp;hellip; But, the sad part follows.&lt;/p&gt;
&lt;p&gt;Due to using manual frame layout, I lost considerable amount of time on those projects in total. Writing manual frame layout is very easy, but extremely tedious and fragile. I had to take the time to learn Autolayout properly, and make it work.&lt;/p&gt;
&lt;h2&gt;Master of Autolayout&lt;/h2&gt;
&lt;p&gt;Let me go ahead and say this: The master of autolayout is &lt;a href="https://github.com/PureLayout/PureLayout"&gt;PureLayout&lt;/a&gt;. Let&amp;rsquo;s see why&amp;hellip;&lt;/p&gt;
&lt;p&gt;I recently started yet another client project, and true to my earlier conviction, I&amp;rsquo;ve went full-blown Storyboard + Autolayout. What made matters even better was that the client was OK with supporting iOS 9+, pretty suh-weet, for only one reason: &lt;code&gt;UIStackView&lt;/code&gt;. Let&amp;rsquo;s leave that for another day .. For now, autolayout!&lt;/p&gt;
&lt;p&gt;So, I was happily building the project, using autolayout all over the place, until I hit my first serious hurdle. The client wants to implement an intimidating looking transition. I can&amp;rsquo;t post the assets here, but try to imagine it with me:&lt;/p&gt;
&lt;p&gt;&amp;ldquo;There is a view with a stack of cards in the middle somewhere. When a card is tapped, it expands to fill the screen, and then scales back down when closed.&amp;rdquo; &lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t simply manipulate the view&amp;rsquo;s frame right away, since it is embedded within the view hierarchy. So, the approach I thought of was the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Remove the view, and add it as a direct subview of the key window.&lt;/li&gt;
&lt;li&gt;scale up the view&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Sounds pretty reasonable &amp;hellip; But this is where autolayout haunted me.&lt;/p&gt;
&lt;p&gt;After writing the code above, it simply didn&amp;rsquo;t work. I would end up with an empty screen &amp;hellip; Debugging the view hierarchy using Xcode and Chisel, I can see that the transitioning view&amp;rsquo;s frame always ends up being all zeros. Why??&lt;/p&gt;
&lt;p&gt;The experimentation began &amp;hellip; I replaced it with a dummy view, it worked like a charm. I replaced it with a new copy of itself, and worked, but a bit funky &amp;hellip; I am missing something! Finally, setting &lt;code&gt;translateAuto..&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; made the view at least appear .. Oh no, an autolayout problem! Do I really want to bother with that? Should I just stick with what I know? &amp;hellip; Time to start learning new stuff!!!&lt;/p&gt;
&lt;p&gt;So, I add PureLayout into my Podfile, created a container view for the transitioning view, and used &lt;code&gt;autoPinEdgesToSuperviewEdges&lt;/code&gt;. That was the end of it &amp;hellip; The solution was insanely simple and worked like a charm! I guess the takeaway here is to either fully embrace Autolayout, or not. If you decide to embrace autolayout, just do yourself a favor and get PureLayout, it&amp;rsquo;s kickass.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I have mixed feelings about this .. I am glad and relieved for finding this solution, but also distressed at the fact that I&amp;rsquo;ve missed it for so many other projects. Well, our only choice ever in life is to look forward!&lt;/p&gt;</content><category term="posts"></category><category term="autolayout"></category><category term="swift"></category><category term="purelayout"></category><category term="github"></category><category term="opensource"></category><category term="ios"></category><category term="uikit"></category><category term="uiview"></category><category term="constraints"></category><category term="layout"></category><category term="snippet"></category></entry><entry><title>Generic Constraints with Optionals</title><link href="https://mazyod.com/blog/2015/11/20/generic-constraints-with-optionals/" rel="alternate"></link><published>2015-11-20T13:13:34+00:00</published><updated>2015-11-20T13:13:34+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-20:/blog/2015/11/20/generic-constraints-with-optionals/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been spending a lot of time polishing and testing a collection of Swift frameworks and releasing them on github. &lt;a href="http://kitz.io"&gt;You can see the website here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The lessons learned from this experience were unbelievable. There is way more to Swift that I could have ever imagined. The …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been spending a lot of time polishing and testing a collection of Swift frameworks and releasing them on github. &lt;a href="http://kitz.io"&gt;You can see the website here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The lessons learned from this experience were unbelievable. There is way more to Swift that I could have ever imagined. The fun part is, each kit in the project comes with its own design problems, and hence requires different approaches and tapping into more amazing Swift features.&lt;/p&gt;
&lt;p&gt;For this post, I&amp;rsquo;ll be going over a design challenge I faced when writing &lt;a href="https://github.com/SwiftKitz/Storez"&gt;Storez&lt;/a&gt;. &lt;/p&gt;
&lt;h2&gt;Conformance&lt;/h2&gt;
&lt;p&gt;So, Storez is a a very flexible Key/Value store for Swift that allows end-developers to easily define their keys in a type-safe manner (with custom behaviors). The biggest challenge faced when doing that is the &amp;ldquo;type-safe&amp;rdquo; part. How do you ensure that?&lt;/p&gt;
&lt;p&gt;Well, let&amp;rsquo;s take the &lt;code&gt;UserDefaultsStore&lt;/code&gt; as an example. It uses &lt;code&gt;NSUserDefaults&lt;/code&gt; as an underlying persistence store. &lt;code&gt;NSUserDefaults&lt;/code&gt; doesn&amp;rsquo;t support every single type of object, only a certain subset. How do we make sure that objects to be stored can be serialized to those types?&lt;/p&gt;
&lt;p&gt;Protocol conformance is the key! By defining the following protocol:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// inherits from class, since we need to cast it to AnyObject&lt;/span&gt;
&lt;span class="kd"&gt;protocol&lt;/span&gt; &lt;span class="nc"&gt;UserDefaultsSerializable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;class&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 then &amp;ldquo;tag&amp;rdquo; the classes which are supported by the store:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="bp"&gt;NSNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserDefaultsSerializable&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="bp"&gt;NSDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserDefaultsSerializable&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="bp"&gt;NSData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserDefaultsSerializable&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we write two simple &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt; functions to access the store:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SerializableType&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;V&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="n"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objectForKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;V&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;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&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="n"&gt;SerializableType&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="n"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setObject&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="n"&gt;forKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;defaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;synchronize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above code is a complete example of providing a safe API on top of &lt;code&gt;NSUserDefaults&lt;/code&gt;&amp;hellip; But, adding custom type support would be nice, won&amp;rsquo;t it?&lt;/p&gt;
&lt;h2&gt;Convertibles&lt;/h2&gt;
&lt;p&gt;This time, we use &amp;ldquo;conformance&amp;rdquo; to provide a set or rules for custom objects that want to store themselves in the key-value store. Here is the one written in Storez:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cm"&gt;/** Other types can conform to this protocol to add  support.&lt;/span&gt;
&lt;span class="cm"&gt;    It simply requires the class to convert to and from one of&lt;/span&gt;
&lt;span class="cm"&gt;    the supported types.&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;protocol&lt;/span&gt; &lt;span class="nc"&gt;UserDefaultsConvertible&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;typealias&lt;/span&gt; &lt;span class="n"&gt;UnderlyingType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UserDefaultsSerializable&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;decode&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="n"&gt;UnderlyingType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;UnderlyingType&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kr"&gt;get&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;This is really interesting, isn&amp;rsquo;t it? First, we provide a generic type requirement, which is furthermore constrained to a &lt;code&gt;UserDefaultsSerializable&lt;/code&gt; type. Then, the conforming type needs to provide two function implementations, one for decoding (de-serializing), and one for encoding (serializing).&lt;/p&gt;
&lt;p&gt;Note, even an enum can easily be a conforming type! Since it is a pure Swift protocol, there are absolutely no limitations to which type can add support.&lt;/p&gt;
&lt;p&gt;One last caveat remains .. What about non-optionals? If you look closely at the &lt;code&gt;get&lt;/code&gt; function, it always returns an optional. What if we wanted to support non optional values, that return some default value when the persisted value doesn&amp;rsquo;t exist? This presents its own set of challenges, since we now have to provide two separate flows for option, and non-optional types.&lt;/p&gt;
&lt;p&gt;Read on&amp;hellip;&lt;/p&gt;
&lt;h2&gt;Get Under Optional Skin&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s first see how we provide the two &lt;code&gt;get&lt;/code&gt; variations:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntryType&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValueType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SerializableType&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValueType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultValue&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;EntryType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SerializableType&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ValueType&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;V&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="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;V&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="n"&gt;_get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;key&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;So, what do we have here&amp;hellip; The first method is the &amp;ldquo;nonnull&amp;rdquo; variant which always returns a non-optional value, while the second method simply returns a nullable value.&lt;/p&gt;
&lt;p&gt;The key difference between these two methods is the way we check to make sure that the value conforms to &lt;code&gt;UserDefaultsSerializable&lt;/code&gt; type. In the first method, it&amp;rsquo;s pretty straight forward. We immediately assert that the &lt;code&gt;ValueType&lt;/code&gt; of the &lt;code&gt;EntryType&lt;/code&gt; is a conforming type.&lt;/p&gt;
&lt;p&gt;For optionals, it was whole journey to reach this final, succulent form. When you look at it now, it feels very natural and straight-forward! It basically says: Define two generic types, one is the &lt;code&gt;EntryType&lt;/code&gt; and another is a value type that conforms to &lt;code&gt;UserDefaultsSerializable&lt;/code&gt;. Then, simply make sure that the &lt;code&gt;EntryType&lt;/code&gt;&amp;rsquo;s &lt;code&gt;ValueType&lt;/code&gt; is an optional of the conforming value type!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The power of Swift is just mind blowing. I&amp;rsquo;ve worked quite a bit with C++ generics, and they are much more flexible, but no where as safe and well defined as Swift&amp;rsquo;s.&lt;/p&gt;</content><category term="posts"></category><category term="swift"></category><category term="code"></category><category term="programming"></category><category term="xcode"></category><category term="generics"></category><category term="optional"></category><category term="nullability"></category><category term="conformance"></category><category term="inheritance"></category><category term="typealias"></category><category term="constraints"></category></entry><entry><title>UIApplication Trap</title><link href="https://mazyod.com/blog/2015/11/18/uiapplication-trap/" rel="alternate"></link><published>2015-11-18T17:03:03+00:00</published><updated>2015-11-18T17:03:03+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-18:/blog/2015/11/18/uiapplication-trap/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;To all my readers out there .. An apology is in order. I have been blogging non-stop for a while, but there was a very unsettling series of sudden pauses recently! I promise it wasn&amp;rsquo;t due to lack of motivation nor interesting topics .. It was a simple matter of …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;To all my readers out there .. An apology is in order. I have been blogging non-stop for a while, but there was a very unsettling series of sudden pauses recently! I promise it wasn&amp;rsquo;t due to lack of motivation nor interesting topics .. It was a simple matter of prioritization.&lt;/p&gt;
&lt;p&gt;Working on about 6 project at the same time is just not something I&amp;rsquo;ve been used to, since I usually put my all into one single thing. Believe me when I say, spreading out like this is much more rewarding, since all your eggs are no longer in one basket.&lt;/p&gt;
&lt;p&gt;In all cases! With that lifestyle, returning to &lt;a href="http://habitica.com"&gt;Habitica&lt;/a&gt; was a no-brainer. With Habitica back in the picture, its time to level up like crazy!!&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/lvlup.gif"&gt;&lt;/p&gt;
&lt;h2&gt;The Wrath of the Singleton&lt;/h2&gt;
&lt;p&gt;Singletons are very handy, and I don&amp;rsquo;t even remember how many times I&amp;rsquo;ve blogged about them &amp;hellip; Unfortunately, I ran into one of those cases where it just kicks your ass.&lt;/p&gt;
&lt;p&gt;The code I have in my app is like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NotificationsMigration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MigrationTask&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;shouldExecute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;previousVersion&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Bool&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;previousVersion&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;2&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;execute&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="bp"&gt;UIApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sharedApplication&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;cancelAllLocalNotifications&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;So, in my app I can easily define subclass of &lt;code&gt;MigrationTask&lt;/code&gt; in order to add code that should be run only once when migrating from a previous version. &lt;/p&gt;
&lt;p&gt;With that said, this migration code is suppose to cleanup previous local notifications because the new version of the app handles notifications in a different way. If I don&amp;rsquo;t do this, users migrating from the old version will experience double notifications (ones that are setup previously, and new ones setup by the new version).&lt;/p&gt;
&lt;p&gt;Well, that looks nice and dandy! There is just &lt;em&gt;no way&lt;/em&gt; this code has a bug, right? There is no need to test it, right? Right, I thought! .. and boy was I mistaken&amp;hellip;&lt;/p&gt;
&lt;p&gt;After publishing the app to the AppStore (Yes, it&amp;rsquo;s that bad), I got a horde of users coming at me complaining about seeing double notifications firing! What?! Why?! How?!!?!&lt;/p&gt;
&lt;p&gt;I had no choice but to put a break point there, and see what was going on. Was the code even reached? Yes, the code reaches the statements and executes perfectly?? WHY?! I brushed it as a glitch in iOS, and submitted another update with other fixes &amp;hellip; No, that&amp;rsquo;s not the end of it.&lt;/p&gt;
&lt;p&gt;While refactoring another part of the app that dealt with notifications as well, I started testing the new code. After running the app, I noticed that notifications were not being scheduled at all &amp;hellip; The code was this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;application&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheduleLocalNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;notification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;app&lt;/code&gt; variable was captured by calling &lt;code&gt;UIApplication&lt;/code&gt;&amp;rsquo;s &lt;code&gt;sharedApplication()&lt;/code&gt; accessor as soon as the object is initialized. That was really weird, why won&amp;rsquo;t it get scheduled?&lt;/p&gt;
&lt;p&gt;By doing some excessive debugging and investigative work, I noticed that this object is initialized before:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;UIApplicationMain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unsafeArgv&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NSStringFromClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppDelegate&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Yes, I override &lt;code&gt;main.swift&lt;/code&gt;, and do some stuff there necessary for language settings, and somehow this object initialization slipped there! To my pleasant surprise, querying for &lt;code&gt;sharedApplication&lt;/code&gt; at that point returns some dummy object! Not even &lt;code&gt;nil&lt;/code&gt;! The app continued to &amp;ldquo;not crash&amp;rdquo;, but doesn&amp;rsquo;t function properly &lt;code&gt;&amp;gt;_&amp;lt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After suffering from this singleton wrath, I appropriately moved most of the code that executes before the &lt;code&gt;UIApplicationMain&lt;/code&gt; call into the app itself, somewhere where it executes after &lt;code&gt;applicationDidFinishLaunching&lt;/code&gt; is called.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Seemingly simple tweaks in the code are still considered &amp;ldquo;rewrites&amp;rdquo; if they change the behavior of the program. Rewrites are hard, because they need to be tested thoroughly, and testing itself is hard. That is probably the topic of the next post, so stay tuned!&lt;/p&gt;</content><category term="posts"></category><category term="uiapplication"></category><category term="shared"></category><category term="application"></category><category term="ios"></category><category term="swift"></category><category term="launch"></category><category term="main"></category><category term="xcode"></category><category term="weird"></category><category term="bug"></category><category term="programming"></category><category term="debugging"></category><category term="broken"></category></entry><entry><title>Where is Maz?</title><link href="https://mazyod.com/blog/2015/11/07/where-is-maz/" rel="alternate"></link><published>2015-11-07T13:35:42+00:00</published><updated>2015-11-07T13:35:42+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-07:/blog/2015/11/07/where-is-maz/</id><summary type="html">&lt;p&gt;&lt;span style="font-size: 72pt;"&gt;🇯🇵 Tokyo&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;Where Next&lt;/h1&gt;
&lt;p&gt;Just staying in Tokyo for a while :D&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;About This Page&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A friend said for fun:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We need a WhereIsMaz.com site, we never get a hold of you!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, I decided to make it anyway, so here I am!&lt;/p&gt;
&lt;p&gt;The reason for this is my current …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;span style="font-size: 72pt;"&gt;🇯🇵 Tokyo&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;Where Next&lt;/h1&gt;
&lt;p&gt;Just staying in Tokyo for a while :D&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;About This Page&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A friend said for fun:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We need a WhereIsMaz.com site, we never get a hold of you!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well, I decided to make it anyway, so here I am!&lt;/p&gt;
&lt;p&gt;The reason for this is my current lifestyle as a &lt;a href="http://nomadlist.com"&gt;digital nomad&lt;/a&gt; means, I am just constantly traveling, and never really making up my mind on the next destination till one week before .. At most.&lt;/p&gt;</content><category term="posts"></category><category term="lol"></category><category term="rant"></category><category term="life"></category><category term="haidar"></category><category term="idea"></category></entry><entry><title>App Submission Nightmare</title><link href="https://mazyod.com/blog/2015/11/01/app-submission-nightmare/" rel="alternate"></link><published>2015-11-01T10:36:47+00:00</published><updated>2015-11-01T10:36:47+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-11-01:/blog/2015/11/01/app-submission-nightmare/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s that time of the year where I need to submit an app to the AppStore. This time around, I had a completely new setup that I&amp;rsquo;ve never attempted to ship before. As expected, since it&amp;rsquo;s a new setup, it came with its own submission error …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s that time of the year where I need to submit an app to the AppStore. This time around, I had a completely new setup that I&amp;rsquo;ve never attempted to ship before. As expected, since it&amp;rsquo;s a new setup, it came with its own submission error variety.&lt;/p&gt;
&lt;h2&gt;The Setup&lt;/h2&gt;
&lt;p&gt;My setup is quite complicated, and neatly sits in the edge cases of Xcode project setups.&lt;/p&gt;
&lt;h3&gt;The Workspace&lt;/h3&gt;
&lt;p&gt;The project workspace and directory structure looks something like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Workspace&lt;ul&gt;
&lt;li&gt;Framework1.xcodeproj&lt;/li&gt;
&lt;li&gt;Framework2.xcodeproj&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;li&gt;Framework10.xcodeproj&lt;/li&gt;
&lt;li&gt;MainAppProject&lt;ul&gt;
&lt;li&gt;Framework1.xcodeproj&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;li&gt;Framework10.xcodeproj&lt;/li&gt;
&lt;li&gt;MainAppGroup&lt;/li&gt;
&lt;li&gt;MainAppUnitTests&lt;/li&gt;
&lt;li&gt;MainAppUITests&lt;/li&gt;
&lt;li&gt;TodayExtensionGroup&lt;/li&gt;
&lt;li&gt;AppleWatchExtensionGroup&lt;/li&gt;
&lt;li&gt;AppleWatchAppGroup&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Pods&lt;/li&gt;
&lt;li&gt;Pods&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is what we are dealing with here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We have 10 Framework projects + 2 cocoapods projects + 1 iOS app project&lt;/li&gt;
&lt;li&gt;Everything is Swift based, except Framework1, which is Objc.&lt;/li&gt;
&lt;li&gt;The main app depends on cocoapods as well as all included framework projects&lt;/li&gt;
&lt;li&gt;One of the framework projects also depends on cocoapods&lt;/li&gt;
&lt;li&gt;The main app itself has 6 targets&lt;ol&gt;
&lt;li&gt;iOS app&lt;/li&gt;
&lt;li&gt;unit tests&lt;/li&gt;
&lt;li&gt;UI tests&lt;/li&gt;
&lt;li&gt;today extension&lt;/li&gt;
&lt;li&gt;AppleWatch app&lt;/li&gt;
&lt;li&gt;AppleWatch extension&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Submission and Dominance&lt;/h2&gt;
&lt;p&gt;At least, this is the game Xcode was playing .. &lt;/p&gt;
&lt;h3&gt;Code Signing &amp;amp; Provisioning&lt;/h3&gt;
&lt;p&gt;First problem that every iOS developer on earth faces came jumping at me:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Code signing in today extension doesn&amp;rsquo;t match provisioning profile&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I checked the today extension target, and it had a bundle ID that seemed different than the one I had &amp;hellip; Instead of fighting Xcode, I launched &lt;a href="http://github.com/fastlane/sigh"&gt;sigh&lt;/a&gt; and typed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;sigh&lt;span class="w"&gt; &lt;/span&gt;renew&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;com.ArabianDevs.PrayerTimes.today-extension&lt;span class="w"&gt; &lt;/span&gt;--force
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Warning Galore&lt;/h3&gt;
&lt;p&gt;For some reason, Xcode was throwing 100s of warnings about &amp;ldquo;stripping sybmbols&amp;rdquo;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;warning: skipping copy phase strip, binary is code signed&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First search through stackoverflow and google led me to disable &amp;ldquo;strip debug symbols during copy&amp;rdquo; for release builds as well as debug. After researching more about it for this article, I read an answer from a TestFlight engineer that this bloats the app by about 30% - 50%, which is insane. So, better just ignore this harmless warning.&lt;/p&gt;
&lt;h3&gt;Archiving&lt;/h3&gt;
&lt;p&gt;Finally! The archive is complete, and showing up in Organizer&amp;hellip; Wait, why is it listed under &amp;ldquo;Other Items&amp;rdquo;, and not iOS apps?! I can&amp;rsquo;t submit to the AppStore this way :(&lt;/p&gt;
&lt;p&gt;Most answers on google point you to making sure that you set &amp;ldquo;Skip install&amp;rdquo; to true for all subproject frameworks and libraries&amp;hellip; I checked, and double checked all 10 frameworks several times, they were all correctly configured.&lt;/p&gt;
&lt;p&gt;I had no idea what was going on, but the only thing I could do is inspect the generated archive, so I did. Opening it revealed that in the &lt;code&gt;Products&lt;/code&gt; directory, there was &amp;ldquo;/Library/Frameworks/Framework1.framework&amp;rdquo; &amp;hellip; Why the heck was it there??&lt;/p&gt;
&lt;p&gt;Coincidently, Framework1 was the only ObjC framework in the lot, so that aroused my suspicion. However, after looking more closely at the project, I realized that it also utilizes Cocoapods! I recall reading that Cocoapods had issues with archiving frameworks pre version 0.39.0 .. Checking Cocoapods for that framework, and true enough, it was built with cocoapods 0.38.2.&lt;/p&gt;
&lt;p&gt;Thankfully, all it took was another &lt;code&gt;pod install&lt;/code&gt;, and cocoapods took care of upgrading the project. Archiving the app again made it appear under iOS Apps! Yay!&lt;/p&gt;
&lt;h3&gt;Submitting&lt;/h3&gt;
&lt;p&gt;So, it&amp;rsquo;s finally time to hit that &lt;code&gt;Submit&lt;/code&gt; button in Organizer, and hope for the best &amp;hellip; That didn&amp;rsquo;t go far at all. After choosing the team and hitting submit, I immediately ran into this error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The archive did not contain DVTFilePath: X: &amp;lsquo;X/Library/Developer/Xcode .. X.xcarchive/BCSymbolMaps .. .bcsymbolmap&amp;rsquo;&amp;gt; as expected.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That was a really weird error to get .. I remembered that my binary isn&amp;rsquo;t bitcode compatible, so I unchecked that &amp;hellip; No dice. Searching online led me to &lt;a href="https://forums.developer.apple.com/thread/14729"&gt;this post&lt;/a&gt;. Surely enough, after unchecking the &amp;ldquo;include app symbols&amp;rdquo;, the error went away .. Phew.&lt;/p&gt;
&lt;h3&gt;Validation&lt;/h3&gt;
&lt;p&gt;After the app started validating with iTunes connect, that is when things got rowdy. I got 4 annoying errors, with varying duplication of each:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;Realm&lt;/code&gt; contains unsupported architecture:&lt;br /&gt;&lt;/li&gt;
&lt;li&gt;AppleWatch app size exceeds permitted 50 MB&lt;/li&gt;
&lt;li&gt;AppleWatch missing 44x44 icon&lt;/li&gt;
&lt;li&gt;Framework8 contains a framework in its belly, and causes an error&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The exact &lt;strong&gt;Realm&lt;/strong&gt; error was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Unsupported architectures.  The executable for xxxx/Realm.framwork contains unsupported architectures [x86_64, i386]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Thankfully, I had just missed a step in integrating the framework&amp;hellip;&lt;/p&gt;
&lt;p&gt;As for the &lt;strong&gt;AppleWatch&lt;/strong&gt; issues, I was easily able to reduce the size by compressing the icon images using &lt;a href="http://pngmini.com/"&gt;ImageAlpha&lt;/a&gt;. How much, you say? saved about 7.5 MB!&lt;/p&gt;
&lt;p&gt;The second, and more important time save was by setting the &amp;ldquo;Embedded content contains Swift&amp;rdquo; to &amp;ldquo;NO&amp;rdquo; in the AppleWatch app project settings. The reason I did this is because I noticed that 33 MB of the app size was due to swift libraries being embedded twice in the binary. So, setting the option to false on the main app reduced the size by 16.5 MB! Phew!&lt;/p&gt;
&lt;p&gt;As for the missing icon, I had simply assumed that it was OK to only support Watch OS 2.0 icons, but I actually needed to add Watch OS 1.1 assets to the asset catalog, and accommodate that as well.&lt;/p&gt;
&lt;p&gt;Finally, the embedded &lt;strong&gt;Framework&lt;/strong&gt; error&amp;hellip; Cocoapods strikes again! Framework8 utilizes cocoapods to link against SwiftJSON. In return, I integrate Framework8 manually using Xcode workspaces into the main project.. Apparently, you can&amp;rsquo;t do that for dynamic frameworks.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Invalid Bundle. The bundle at &amp;lsquo;X.app/Frameworks/X.framework&amp;rsquo; contains disallowed file &amp;lsquo;Frameworks&amp;rsquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://github.com/CocoaPods/CocoaPods/issues/3440"&gt;According to this issue&lt;/a&gt;, Cocoapods just insists on embedding the linked framework into its target even if the target is a framework itself. The suggested way to solve the issue is to convert the intermediate framework (Framework8) into a pod itself &amp;hellip;&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/jaa7pj5.jpg"&gt;&lt;/p&gt;
&lt;p&gt;So, instead, I pull SwiftyJSON, build it locally, drop it into the workspace, add it to Framework8 framework search paths (without linking it!!), and finally make sure SwiftyJSON is added to the main app pod file. DONE.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Unfortunately, I didn&amp;rsquo;t write the issues I faced in detail, since I am writing this now after resolving all them issues .. Lesson learned for next time!&lt;/p&gt;</content><category term="posts"></category><category term="appstore"></category><category term="submission"></category><category term="error"></category><category term="apple-watch"></category><category term="xcode"></category><category term="itunes"></category><category term="connect"></category><category term="upload"></category><category term="size"></category><category term="realm"></category><category term="embed"></category><category term="framework"></category><category term="code"></category><category term="signing"></category><category term="archive"></category><category term="generic"></category><category term="provisioning"></category><category term="profile"></category></entry><entry><title>Shipping With Realm</title><link href="https://mazyod.com/blog/2015/10/30/shipping-with-realm/" rel="alternate"></link><published>2015-10-30T15:45:59+00:00</published><updated>2015-10-30T15:45:59+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-10-30:/blog/2015/10/30/shipping-with-realm/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I have recently announced starting to use &lt;a href="http://realm.io"&gt;Realm&lt;/a&gt; for my iOS projects. Then, I had just started using the technology, but didn&amp;rsquo;t really reach shipping stage until now. When it&amp;rsquo;s time to ship, that is when every ugly detail surfaces.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This post is sponsored by &lt;a href="http://fastlane.tools"&gt;fastlane …&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I have recently announced starting to use &lt;a href="http://realm.io"&gt;Realm&lt;/a&gt; for my iOS projects. Then, I had just started using the technology, but didn&amp;rsquo;t really reach shipping stage until now. When it&amp;rsquo;s time to ship, that is when every ugly detail surfaces.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This post is sponsored by &lt;a href="http://fastlane.tools"&gt;fastlane&lt;/a&gt;! I found time to blog while it is busy building my app and generating screenshots.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Use Cases&lt;/h2&gt;
&lt;p&gt;For starters, I&amp;rsquo;ll be going over my use cases for using Realm, and then study each use case separately.&lt;/p&gt;
&lt;h3&gt;Shared Settings&lt;/h3&gt;
&lt;p&gt;The first use case is using Realm to store app settings (preferences), and sharing them across all bundles (Main app, extension, AppleWatch app). This was supremely handled well by Realm, and I probably can&amp;rsquo;t be happier with the setup.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Migration&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Application settings change very easily and quickly. Adding more settings in the future won&amp;rsquo;t be a problem at all thanks to Realm&amp;rsquo;s clean Migration APIs. Breaking the settings down into small tables also helps a lot in managing migrations and changes, so keep that in mind.&lt;/p&gt;
&lt;p&gt;For starters, all you really need to do is set the &lt;code&gt;schemaVersion&lt;/code&gt; property on your &lt;code&gt;Configuration&lt;/code&gt; object to &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Shared Container&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First step is to &lt;a href="https://mazyod.com/blog/2015/01/03/app-groups/"&gt;set up an application group, and get a shared container going&lt;/a&gt;. The shared container will host the Realm files, and as per the docs, they can be accessed concurrently across processes without issues!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;fileManager&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;NSFileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultManager&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;fileManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;containerURLForSecurityApplicationGroupIdentifier&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;group.identifier&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// do something with path&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Simple API&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It is extremely important to have a simple API to read and update the settings, as well as extend the settings later. I probably have never had the pleasure of working with a cleaner API before, Realm takes the cake here as well.&lt;/p&gt;
&lt;p&gt;To minimize duplicate code and stream line settings tables, though, I had to leverage Swift protocol extensions to roll out some convenient accessors.&lt;/p&gt;
&lt;p&gt;First, let&amp;rsquo;s see how my current settings code looks like:
&lt;em&gt;Note: I use capital letters for static accessors&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LocaleSettingsTable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kr"&gt;dynamic&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;languageLocale&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;en&amp;quot;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kr"&gt;dynamic&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;regionLocale&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;en&amp;quot;&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kr"&gt;dynamic&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;timeFormat&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;12&amp;quot;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// get Locale settings:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;language&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LocaleSettingsTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;languageLocale&lt;/span&gt;

&lt;span class="c1"&gt;// update Locale settings:&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;newValue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;ar&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;LocaleSettingsTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentSettings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt;
    &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;languageLocale&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;newValue&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That is all there is to it! There is actually a lot of hidden power behind this concise syntax, so let&amp;rsquo;s dig deeper.&lt;/p&gt;
&lt;p&gt;First, you should be asking: Where is &lt;code&gt;CurrentSettings&lt;/code&gt; class variable coming from? Also, same thing goes to &lt;code&gt;commit&lt;/code&gt; method?&lt;/p&gt;
&lt;p&gt;Aha! Here is where Swift protocol extensions come into play. The common settings functionality is grouped into the protocol extension below:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;protocol&lt;/span&gt; &lt;span class="nc"&gt;SettingsTable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;HostRealm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Realm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kr"&gt;get&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;preCommitHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;    &lt;span class="c1"&gt;// You can validate settings here&lt;/span&gt;
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;postCommitHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;   &lt;span class="c1"&gt;// You can apply more changes here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="nc"&gt;SettingsTable&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="kc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// NotificationCenter key for observers&lt;/span&gt;
    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;NotificationKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&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;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;className&lt;/span&gt;&lt;span class="si"&gt;())&lt;/span&gt;&lt;span class="s"&gt;.On.Update&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// lazy loaded settings&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;CurrentSettings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HostRealm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="bp"&gt;first&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;settings&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="n"&gt;HostRealm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;HostRealm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&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="n"&gt;settings&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kc"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&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="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="n"&gt;preCommitHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;klass&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kc"&gt;dynamicType&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;changes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

            &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;realm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HostRealm&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;!&lt;/span&gt; &lt;span class="n"&gt;realm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;self&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="n"&gt;postCommitHook&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="bp"&gt;NSNotificationCenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultCenter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;postNotificationName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NotificationKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;self&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;preCommitHook&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;postCommitHook&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;Now if you followed that properly, you&amp;rsquo;ll realize that any new settings table can easily get all these goodies by simply conforming to &lt;code&gt;SettingsTable&lt;/code&gt; and implementing the &lt;code&gt;HostRealm&lt;/code&gt; accessor.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="nc"&gt;LocaleSettingsTable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SettingsTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;HostRealm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Realm&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Localez&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SettingsRealm&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;To wrap up this section about &lt;strong&gt;Simple API&lt;/strong&gt;, I&amp;rsquo;ll just say that it was quite important to break my application settings into smaller parts and pieces. This allows Realm tables to evolve independently, therefor giving us granular control over each settings group.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nothing to be said here about performance, really. We have a single object per table, and about 5 tables total. Everything ran fast enough for me to just ignore benchmarking this.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Further Work&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To take this a step further, notifications should work across processes. I am not too worried or keen about taking care of that right now, so meh.&lt;/p&gt;
&lt;h3&gt;Key Value Store&lt;/h3&gt;
&lt;p&gt;The second use case for Realm was to be used as a key-value cache for downloads. The key type is &lt;code&gt;String&lt;/code&gt;, however, the value is a JSON serialized &lt;code&gt;NSData&lt;/code&gt; blob. Finally, we add an auto-updating &lt;code&gt;NSDate()&lt;/code&gt; there to maintain the cache timestamp. This use case is also neatly covered by Realm + Swift generics. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Realm Table&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If we take a look at the Realm part of this sub-system, it is summed up in a few lines of code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CacheTable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kr"&gt;dynamic&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="kr"&gt;dynamic&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;timestamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;NSDate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="kr"&gt;dynamic&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;NSData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kr"&gt;override&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;func&lt;/span&gt; &lt;span class="n"&gt;primaryKey&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&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;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;key&amp;quot;&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;&lt;strong&gt;Generic Wrapper&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As for Swift generics, it&amp;rsquo;s pretty lengthy an can&amp;rsquo;t be fully covered in this article. A quick skim, however, is in order. The wrapper is just two classes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Task&lt;/code&gt;&lt;/strong&gt;&lt;br /&gt;
Wraps the cache by providing an ability to instantiate a network task that automatically writes its result to the Realm cache.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;TaskMeta&lt;/code&gt;&lt;/strong&gt;&lt;br /&gt;
Facilitates the data that describes a &lt;code&gt;Task&lt;/code&gt;. It is typically a URL which we sync the data from, a notification key which gets fired when the cache data is updated, and finally an expiration interval&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is an example of how a &lt;code&gt;Task&lt;/code&gt; is created:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;meta&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TaskMeta&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;urlString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s"&gt;/kpt/tweets&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;
&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;expirationInterval&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.&lt;/span&gt;&lt;span class="n"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timeInterval&lt;/span&gt;
&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notificationKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;On&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TweetsUpdate&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;AnyObject&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="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;updateIfNeeded&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You may notice:
+ &lt;code&gt;Task&amp;lt;[AnyObject]&amp;gt;&lt;/code&gt;: This decides how the network response is parsed
+ &lt;code&gt;1.hour.timeInterval&lt;/code&gt;: This is just a convenience time library I use&lt;/p&gt;
&lt;p&gt;Performance isn&amp;rsquo;t a big issue here. Since network operations are asynchronous by nature, we simply chain them with an asynchronous background access to the cache. Same thing goes to the deserialization.&lt;/p&gt;
&lt;h3&gt;Static Data&lt;/h3&gt;
&lt;p&gt;My final use case was to ship static data with my apps. I had two different types of static data:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Small number of &amp;ldquo;sounds&amp;rdquo; shipped with the app &lt;strong&gt;(39 total)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Large number of &amp;ldquo;prayer times&amp;rdquo; for all the cities in Kuwait &lt;strong&gt;(26k)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Manipulating Static Realm Files&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Dealing with static data was a &lt;strong&gt;huge&lt;/strong&gt; pain, in general, due to the lack of a interpreter interface. Every time I needed to manipulate the data, I had to write full-fledged swift apps to parse and manipulate realm files.&lt;/p&gt;
&lt;p&gt;Once you do that, you&amp;rsquo;ll quickly realize it is no fun. Realm files are very rigid, and quickly throw errors when the schema changes, objects are copied between realms, and possibly the most annoying is dropping existing tables (not possible).&lt;/p&gt;
&lt;p&gt;I swallowed my pride for a good of two days, and dished out two realm files. The sounds realm file worked to date without any real issues. However, the humongous prayer times file wasn&amp;rsquo;t snappy at all. Performance became a bottleneck.&lt;/p&gt;
&lt;p&gt;Thankfully, my data was easy to break down into smaller parts, so that&amp;rsquo;s what I did. Each city&amp;rsquo;s prayer times was moved to a separate realm file, then there was a single realm file with all the cities. Once I did that, a realm file would have 2196 objects, and that brought the performance back up again.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;API&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As for the API, I was easily able to write a nice wrapper around Realm to make the queries really easy and simple. Here is an example of how the &lt;code&gt;City&lt;/code&gt; objects are queried:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="nc"&gt;City&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;RealmSwift&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CityTable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;CitiesRealm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CityTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cityId&lt;/span&gt; &lt;span class="n"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;RealmSwift&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;CityTable&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="bp"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;id == %@&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;City&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="n"&gt;Results&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="bp"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;City&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$0&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;The main issue here is that I duplicate the &lt;code&gt;CityTable&lt;/code&gt; class, and create a light-weight &lt;code&gt;City&lt;/code&gt; struct that is returned to the caller. However, by doing that, I can now essentially switch out my core static data provider anytime I like without worrying about app wide changes. Also, I can control Realm&amp;rsquo;s complexity, since changing these Realm objects is a no-no (it&amp;rsquo;s a read-only realm!).&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Realm is definitely better than any other persistence option, IMO. The only worry is performance. If you need that, you might as well roll out your own in memory map and use that.&lt;/p&gt;
&lt;p&gt;Also, Fastlane has finished running a while ago, so time to get back to work!&lt;/p&gt;</content><category term="posts"></category><category term="realm"></category><category term="ios"></category><category term="swift"></category><category term="xcode"></category><category term="app"></category><category term="appstore"></category><category term="release"></category><category term="impression"></category><category term="review"></category><category term="migration"></category><category term="schema"></category><category term="version"></category></entry><entry><title>Welcome to Realm</title><link href="https://mazyod.com/blog/2015/09/09/welcome-to-realm/" rel="alternate"></link><published>2015-09-09T00:01:28+00:00</published><updated>2015-09-09T00:01:28+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-09-09:/blog/2015/09/09/welcome-to-realm/</id><summary type="html">&lt;p&gt;Finally .. I&amp;rsquo;ve made the move to &lt;a href="http://realm.io/"&gt;Realm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/realm-logo.png"&gt;&lt;/p&gt;
&lt;h2&gt;What Happened?&lt;/h2&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been working an iOS project for some client, and obviously went with Swift for everything. The app is a very typical RESTful consumer, with a relatively simple data model.&lt;/p&gt;
&lt;p&gt;For the first phase of the app, I …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Finally .. I&amp;rsquo;ve made the move to &lt;a href="http://realm.io/"&gt;Realm&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/realm-logo.png"&gt;&lt;/p&gt;
&lt;h2&gt;What Happened?&lt;/h2&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve been working an iOS project for some client, and obviously went with Swift for everything. The app is a very typical RESTful consumer, with a relatively simple data model.&lt;/p&gt;
&lt;p&gt;For the first phase of the app, I focused on implementing and polishing the UI, and everything was great. Then, the time came .. I had to integrate with the backend.&lt;/p&gt;
&lt;p&gt;I sticked to my guns, created a new core data model, and started creating all those various entities. Life was good.&lt;/p&gt;
&lt;p&gt;While defining the models, generating &lt;code&gt;NSManagedObject&lt;/code&gt; subclasses, and integrating the JSON mapping using &lt;code&gt;MagicalRecord&lt;/code&gt;, things slowly started to break.&lt;/p&gt;
&lt;p&gt;The first annoyance was when I got a crash from Swift&amp;rsquo;s unexpectedly unwrapped and found nil thingy. Apparently, generated Swift models don&amp;rsquo;t mark their properties as optional .. Not even implicitly unwrapped. I took a breath, downloaded Xcode 7 and generated the classes there.&lt;/p&gt;
&lt;p&gt;Second annoyance was that now, everything was optional! Argh! Who cares, just wrap with some getters or use MVVM or something. Not a big deal &amp;hellip;&lt;/p&gt;
&lt;p&gt;Finally, two things happened simultaneously:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I was trying to get to-many relationship to work, and &lt;code&gt;MagicalRecord&lt;/code&gt; failed.&lt;/li&gt;
&lt;li&gt;Swift compiler crashed &amp;hellip;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="image" src="/images/justjimmar_2015-Jul-22.jpg"&gt;&lt;/p&gt;
&lt;p&gt;Seriously&amp;hellip;&lt;/p&gt;
&lt;h2&gt;What now?&lt;/h2&gt;
&lt;p&gt;My best course of action was to move all the CoreData crap to Objective-C land, where I&amp;rsquo;m comfortable working with. Thinking of that made my head spin because of all the bridging management I had to do (nullability, generics).&lt;/p&gt;
&lt;p&gt;It is a no-brainer. I shall use Realm, and it shall work.&lt;/p&gt;
&lt;h2&gt;Zero to One&lt;/h2&gt;
&lt;p&gt;I hope Peter doesn&amp;rsquo;t sue me on this one.. In any case, time is short, and lots of code to be migrated, so I had to start right away.&lt;/p&gt;
&lt;h4&gt;NSManagedObejct -&amp;gt; Object&lt;/h4&gt;
&lt;p&gt;Migrating the model classes to realm was a delight thanks to a few search and replace, regex-fu, and &lt;code&gt;zmv&lt;/code&gt;s. The checklist is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Change &lt;code&gt;NSManagedObject&lt;/code&gt; superclass to &lt;code&gt;Object&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;replace &lt;code&gt;@NSManaged&lt;/code&gt; with &lt;code&gt;dynamic&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Inverse relationships were all removed, normal relationships were easily migrated, and the actual properties were assigned default values. Next!&lt;/p&gt;
&lt;h4&gt;NSManagedObjectContext -&amp;gt; Realm&lt;/h4&gt;
&lt;p&gt;Since I haven&amp;rsquo;t proven that this app needs background data saving and processing, I&amp;rsquo;ve been using the main thread for data operations. The app isn&amp;rsquo;t ready to ship yet, as well, so migration hasn&amp;rsquo;t been set up properly yet. I&amp;rsquo;m glad I haven&amp;rsquo;t invested in those yet, since look. I&amp;rsquo;ve completely rewired the data layer!&lt;/p&gt;
&lt;p&gt;It was simple to migrate &lt;code&gt;NSManagedObjectContext&lt;/code&gt; by creating a &lt;code&gt;Realms.swift&lt;/code&gt; class with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;Foundation&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;RealmSwift&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;MainRealm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Realm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;config&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Realm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;defaultConfiguration&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;realm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Realm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;realm&lt;/span&gt;
&lt;span class="p"&gt;}()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I plan to add two more realms here, and setup all the configurations properly, but that&amp;rsquo;s about it.&lt;/p&gt;
&lt;h4&gt;JSON Mapping&lt;/h4&gt;
&lt;p&gt;Realm had recently published a talk that discusses using &lt;code&gt;Mantle&lt;/code&gt; as a way to approach JSON serialization&amp;hellip; I didn&amp;rsquo;t like that approach at all. As far as I could tell, it involved rewriting the model classes into &lt;code&gt;Mantle&lt;/code&gt; subclasses, and .. so much duplication is what I was seeing.&lt;/p&gt;
&lt;p&gt;Instead, I imported &lt;code&gt;SwiftyJSON&lt;/code&gt;, and started rolling out my own simple mapper using &lt;code&gt;convenience init&lt;/code&gt; on Realm &lt;code&gt;Object&lt;/code&gt; extension. I bumped into a real annoyance here, but it was Swift&amp;rsquo;s issue:&lt;/p&gt;
&lt;p&gt;The idea was that each model class would take a json, deserialize, then pass the json to it&amp;rsquo;s superclass, so it could continue building the object. That didn&amp;rsquo;t work.&lt;/p&gt;
&lt;p&gt;Apparently, Swift doesn&amp;rsquo;t yet support overriding functions in Extensions (Swift 1.2). I mean, if you define a function in class &lt;code&gt;A&lt;/code&gt; extension, and override it in class &lt;code&gt;B&lt;/code&gt; extension, where &lt;code&gt;B&lt;/code&gt; inherits from &lt;code&gt;A&lt;/code&gt;, Swift compiler will complain. That annoyance made me break the model hierarchy into a flat hierarchy, where all models inherit from &lt;code&gt;RealmSwift.Object&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s not too bad. The only annoyance is that I had to repeat the primary key declaration across all objects, instead of having a root class with an &lt;code&gt;id&lt;/code&gt; property and primary key. Once Swift implements this feature, that code can go away!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;Foundation&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="nc"&gt;SwiftyJSON&lt;/span&gt;


&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="nc"&gt;ServerResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kr"&gt;convenience&lt;/span&gt; &lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kc"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;msg&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;stringValue&lt;/span&gt;
        &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;status&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="n"&gt;stringValue&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;h2&gt;OK, I Lied&lt;/h2&gt;
&lt;p&gt;I really hope you are not reading this waiting for the part where I talk about hooking up Realm with your UI, since I didn&amp;rsquo;t do that yet ^^;. I have a rough idea how I will approach this, but it&amp;rsquo;s definitely not as neat as &lt;code&gt;NSFetchedResultsController&lt;/code&gt;. Dat class is da bomb.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;When the initial setup is just so smooth, and the issues I faced are just a tiny learning curve mixed with a few road-bumps unrelated to Realm, I gotta say my iOS development game is gonna change.&lt;/p&gt;
&lt;p&gt;Realm is approaching v1.0 rapidly, with null-support just around the corner. I find it hard to think I&amp;rsquo;ll be switching back to CoreData .. Ever.&lt;/p&gt;</content><category term="posts"></category><category term="realm"></category><category term="ios"></category><category term="swift"></category><category term="core-data"></category><category term="sqlite"></category><category term="data"></category><category term="persistence"></category><category term="rest"></category><category term="api"></category><category term="backend"></category><category term="sync"></category><category term="json"></category><category term="parse"></category><category term="mapping"></category><category term="mantle"></category><category term="swiftyJSON"></category><category term="github"></category></entry><entry><title>X-Men</title><link href="https://mazyod.com/blog/2015/08/10/x-men/" rel="alternate"></link><published>2015-08-10T00:32:31+00:00</published><updated>2015-08-10T00:32:31+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-08-10:/blog/2015/08/10/x-men/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This C++ language never ceases to amaze me .. Something new to learn everyday, and today I learned that mutating creatures aren&amp;rsquo;t X-Men exclusive, C++ has those, too!! The first time I was &lt;code&gt;mutating&lt;/code&gt; was actually in Swift. In Swift, struct functions are &lt;code&gt;const&lt;/code&gt; by default, unless declared mutating …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;This C++ language never ceases to amaze me .. Something new to learn everyday, and today I learned that mutating creatures aren&amp;rsquo;t X-Men exclusive, C++ has those, too!! The first time I was &lt;code&gt;mutating&lt;/code&gt; was actually in Swift. In Swift, struct functions are &lt;code&gt;const&lt;/code&gt; by default, unless declared mutating. For example, the code below doesn&amp;rsquo;t even compile:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="nc"&gt;X&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;y&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; 
    &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;mutateY&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&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;Anyway, &lt;code&gt;mutating&lt;/code&gt; was found in C++, and it seems to serve a different purpose!&lt;/p&gt;
&lt;h2&gt;Injecting the Uranium&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s kick off with some code!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Nice&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;sizeOfSharedContainer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_mutex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;mutating&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Mutex&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_mutex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;std&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_container&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;Imagine the code Without the &lt;code&gt;mutating&lt;/code&gt; keyword being there. Now, look at &lt;code&gt;sizeOfSharedContainer&lt;/code&gt; implementation. You would have to assume that the &lt;code&gt;Lock&lt;/code&gt; constructor takes a &lt;code&gt;const&amp;amp;&lt;/code&gt; of &lt;code&gt;_mutex&lt;/code&gt;, since the method is marked as &lt;code&gt;const&lt;/code&gt;. Reality is, &lt;code&gt;Lock&lt;/code&gt; needs to mutate &lt;code&gt;_mutex&lt;/code&gt;, so other threads accessing &lt;code&gt;_mutex&lt;/code&gt; know another thread is in the critical section! What now?!&lt;/p&gt;
&lt;p&gt;The goal here is to still mark the method as &lt;code&gt;const&lt;/code&gt;, since as far as the logical representation of &lt;code&gt;Nice&lt;/code&gt; is concerned, the object didn&amp;rsquo;t change after the execution of &lt;code&gt;sizeOfSharedContainer&lt;/code&gt;!! We mutated a mutex to ensure thread safety for a short while, then revert it back.&lt;/p&gt;
&lt;p&gt;Lazy developers would immediately remove &lt;code&gt;const&lt;/code&gt; from the method. Fortunately, the developer&amp;rsquo;s code I read wasn&amp;rsquo;t one of the lazy peeps. Adding &lt;code&gt;mutating&lt;/code&gt;, as you probably guessed by now, allows us to overrule the &lt;code&gt;const&lt;/code&gt; restriction for certain data members.&lt;/p&gt;
&lt;h2&gt;Why Haven&amp;rsquo;t I Head of It?&lt;/h2&gt;
&lt;p&gt;I guess I&amp;rsquo;ve never come across it before because it is essentially a double edged sword, much like &lt;code&gt;const_cast&lt;/code&gt;. People use it very carefully, and it probably only makes sense once the program start to become a bit complex. Some workarounds exist, so this feature isn&amp;rsquo;t a dire need, so that&amp;rsquo;s also another reason why only few professionals use it.&lt;/p&gt;
&lt;h2&gt;Other Use Cases&lt;/h2&gt;
&lt;p&gt;Another helpful use case is lazy-loaded variables. Their getters should be marked as &lt;code&gt;const&lt;/code&gt;, but on first access, we would have to mutate the cache variable to store the value once. Just make sure that cache variable is &lt;code&gt;private&lt;/code&gt;!&lt;/p&gt;
&lt;p&gt;A use case I actually thought of, and didn&amp;rsquo;t nab from the Google, is memoization. It is actually derived from the lazy loading concept, lol.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I need to write more interesting posts, with pics and stuff&amp;hellip;&lt;/p&gt;</content><category term="posts"></category><category term="mutating"></category><category term="mutex"></category><category term="lock"></category><category term="poco"></category><category term="c++"></category><category term="library"></category><category term="development"></category><category term="programming"></category><category term="code"></category><category term="scope"></category><category term="const"></category><category term="correct"></category><category term="clean"></category><category term="logic"></category><category term="semantic"></category></entry><entry><title>RAII</title><link href="https://mazyod.com/blog/2015/08/02/raii/" rel="alternate"></link><published>2015-08-02T22:38:51+00:00</published><updated>2015-08-02T22:38:51+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-08-02:/blog/2015/08/02/raii/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Unfortunately, we often overlook cool concepts in programming just because we simply weren&amp;rsquo;t lucky enough to have stumbled upon them during the course of our work. The blame is ultimately on us, for not searching for simpler solutions to our design problem .. I have no idea what kind …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Unfortunately, we often overlook cool concepts in programming just because we simply weren&amp;rsquo;t lucky enough to have stumbled upon them during the course of our work. The blame is ultimately on us, for not searching for simpler solutions to our design problem .. I have no idea what kind of introduction this is, but it is one.&lt;/p&gt;
&lt;h2&gt;Initialization Is Allocation of Resource&lt;/h2&gt;
&lt;p&gt;Well, I spelled it backwards .. RAII stands for Resource Allocation Is Initialization. It also means, Resource Destruction Is Release. This principle, as far as I know, has only been widely used by C++ programmers, and after using it a few times, it simplifies resource management greatly, and fits amazingly well with the OOP mantra.&lt;/p&gt;
&lt;p&gt;So, what in the name of mother bleep is RAII? Let&amp;rsquo;s just see a quick example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Lock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lock&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;_vector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&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;What happened?&lt;/p&gt;
&lt;p&gt;First, we initialized what looks like an &amp;ldquo;unused&amp;rdquo; lock object. Then, we create some data and append it to an instance variable &amp;hellip; Doesn&amp;rsquo;t make much sense without knowing the internals of the &lt;code&gt;Lock&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;The lock object is actually quite simply doing two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Acquiring a semaphore/lock on the code section in the constructor&lt;/li&gt;
&lt;li&gt;Releasing the semaphore/lock in the destructor&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If you think about it in the real world, you bring a lock, and now you have exclusive access to the critical section. after you finish your stuff, the scope will end, and the object destructor will be called automatically, so the lock will be released.&lt;/p&gt;
&lt;p&gt;The great thing about this is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It abstracts the details of how the lock is implemented&lt;/li&gt;
&lt;li&gt;It makes perfect sense to OOP developers&lt;/li&gt;
&lt;li&gt;It works well even if an exception was thrown in the middle!&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Very simple concepts these days, but they are quite interesting for a mainly ObjC/Swift developer diving into the C++ world.&lt;/p&gt;</content><category term="posts"></category><category term="c++"></category><category term="raii"></category><category term="principle"></category><category term="programming"></category><category term="mantra"></category><category term="design"></category><category term="pattern"></category><category term="cool"></category><category term="snippets"></category><category term="destructor"></category><category term="object"></category><category term="resource"></category><category term="allocation"></category></entry><entry><title>Multiplayer</title><link href="https://mazyod.com/blog/2015/08/02/multiplayer/" rel="alternate"></link><published>2015-08-02T02:00:07+00:00</published><updated>2015-08-02T02:00:07+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-08-02:/blog/2015/08/02/multiplayer/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I am really high on game development these days .. Much of my time and focus is on building this core game &amp;ldquo;framework&amp;rdquo; that will basically be the building block of all future awesomeness. I can&amp;rsquo;t make any compromises at this stage, as the technical debts accumulates insanely fast …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I am really high on game development these days .. Much of my time and focus is on building this core game &amp;ldquo;framework&amp;rdquo; that will basically be the building block of all future awesomeness. I can&amp;rsquo;t make any compromises at this stage, as the technical debts accumulates insanely fast when you&amp;rsquo;re working without a large team.&lt;/p&gt;
&lt;p&gt;Anyways, the idea is to either launch these amazing game series, or somehow get acquired for 500 million pesos. lol, yeah, I am high.&lt;/p&gt;
&lt;h2&gt;Abstraction&lt;/h2&gt;
&lt;p&gt;The main issue with designing a multiplayer game, from the client app perspective, is how to properly abstract away the network events, such that most of the app doesn&amp;rsquo;t really care where the events are coming from or going to. You don&amp;rsquo;t want to litter through out the code base with backend calls, obviously.&lt;/p&gt;
&lt;p&gt;To deal with this design problem, we need to find the right abstraction. What does the network mean to our game? Well, for my game the network is just a pipe that sends local events to a remote player, as well as receive events from the other end of the pipe &amp;hellip; So, the abstraction unit for the game is the player!&lt;/p&gt;
&lt;p&gt;Indeed, imagine you are sitting in a checkers game, and you are playing against an AI, like physically. The game board is the same, you are you obviously, but what changes is that instead of sitting in front of a human being, you will be sitting in front of a robot or something. Same thing goes for a remote player.&lt;/p&gt;
&lt;h2&gt;Materialize&lt;/h2&gt;
&lt;p&gt;Now, we need to materialize the abstraction, and actually implement this setup.&lt;/p&gt;
&lt;p&gt;By creating an abstract player class, we can have a common interface for the main runloop to deal with the players without caring what type of players they are. Basic OOP stuff, moving right along, since designing the player interface is what is actually interesting.&lt;/p&gt;
&lt;p&gt;To do that, let&amp;rsquo;s see what information a real physical player receives throughout the game. A player would obviously be looking at the game board, and knows the game state, so we need to pass the &lt;code&gt;GameLogic&lt;/code&gt; to the player. The player also would see their opponent making moves, so we either send the move to the opponent, or simply pass a &lt;code&gt;GameLogic&lt;/code&gt; update. That way, the player would also know its their turn now.&lt;/p&gt;
&lt;p&gt;That is pretty much it. Anything else you add to the player might be redundant or a mistake in the abstraction. When I first designed the game, I thought the player owned her pieces, but that just complicated things, and it was better to just keep the pieces as part of the game board.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I really hope this post was actually useful, since I didn&amp;rsquo;t even bother add code snippets nor images, so it looks quite dull &amp;hellip; Anyways, happy coding!&lt;/p&gt;</content><category term="posts"></category><category term="multiplayer"></category><category term="online"></category><category term="game"></category><category term="development"></category><category term="challenge"></category><category term="c++"></category><category term="indie"></category><category term="design"></category><category term="architecture"></category><category term="question"></category><category term="rant"></category></entry><entry><title>Graphic Agnostic</title><link href="https://mazyod.com/blog/2015/07/29/graphic-agnostic/" rel="alternate"></link><published>2015-07-29T05:33:44+00:00</published><updated>2015-07-29T05:33:44+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-07-29:/blog/2015/07/29/graphic-agnostic/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve recently committed to writing my whole game on terminal. This had two great advantages:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Worry about graphics later&lt;/strong&gt;
I am 100% focused on the technicality of the game, and low level experience. I don&amp;rsquo;t have to worry about graphic details just yet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Maintainability&lt;/strong&gt;
Using …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve recently committed to writing my whole game on terminal. This had two great advantages:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Worry about graphics later&lt;/strong&gt;
I am 100% focused on the technicality of the game, and low level experience. I don&amp;rsquo;t have to worry about graphic details just yet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Maintainability&lt;/strong&gt;
Using this approach separates the concerns pretty well. This helps us achieve maximum maintainability and testability. UI testing is a pain since the middle ages, and what better way to solve the problem than remove the UI altogether?&lt;/p&gt;
&lt;h2&gt;The Thing&lt;/h2&gt;
&lt;p&gt;I don&amp;rsquo;t really have the time nor motivation to write down all the details, but I made a quick video tutorial about the subject. You can see the project structure, and terminal client, and how awesome it is to develop with this approach:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=326vKdiAn4g"&gt;Youtube link&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The main thing to keep in mind here, &lt;em&gt;do whatever works for you&lt;/em&gt;. I am a real freak when it comes to details, and I want to perfect the app and experience in every way possible, especially technically. That is simply not possible without a solid code design, so having that is extremely important for me.&lt;/p&gt;</content><category term="posts"></category><category term="graphics"></category><category term="game"></category><category term="indie"></category><category term="development"></category><category term="c++"></category><category term="c++11"></category><category term="poco"></category><category term="pocoproject"></category><category term="cli"></category><category term="interface"></category><category term="terminal"></category><category term="command"></category><category term="testing"></category><category term="automation"></category><category term="maintainability"></category><category term="library"></category><category term="integration"></category><category term="functional"></category></entry><entry><title>Will You Be My Friend?</title><link href="https://mazyod.com/blog/2015/07/23/will-you-be-my-friend/" rel="alternate"></link><published>2015-07-23T23:37:28+00:00</published><updated>2015-07-23T23:37:28+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-07-23:/blog/2015/07/23/will-you-be-my-friend/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;A friend is someone who you can share &lt;strong&gt;private&lt;/strong&gt; secrets with, and they will never betray that trust. A friend is someone &lt;strong&gt;you choose&lt;/strong&gt;, not the other way around. A friend makes your life &lt;strong&gt;safe&lt;/strong&gt; by helping you out.&lt;/p&gt;
&lt;p&gt;In short .. Friends are awesome. &lt;/p&gt;
&lt;h2&gt;Friends in C++&lt;/h2&gt;
&lt;p&gt;In C …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;A friend is someone who you can share &lt;strong&gt;private&lt;/strong&gt; secrets with, and they will never betray that trust. A friend is someone &lt;strong&gt;you choose&lt;/strong&gt;, not the other way around. A friend makes your life &lt;strong&gt;safe&lt;/strong&gt; by helping you out.&lt;/p&gt;
&lt;p&gt;In short .. Friends are awesome. &lt;/p&gt;
&lt;h2&gt;Friends in C++&lt;/h2&gt;
&lt;p&gt;In C++, we have things called &amp;ldquo;friend classes&amp;rdquo;. I remember our TA at college making fun of us when we answered the trick question &amp;ldquo;Can private members ever be exposed to an outside class?&amp;rdquo; wrongly..&lt;/p&gt;
&lt;p&gt;Ehm, anyways. As mentioned in the introduction, a friend class is a class you share your &lt;strong&gt;private&lt;/strong&gt; members with. You &lt;strong&gt;choose&lt;/strong&gt; which classes are your friends by declaring them as friend classes in the class definition. Finally, as we will see, this feature will allow you to &lt;strong&gt;safely&lt;/strong&gt; control access to specific &amp;ldquo;dangerous&amp;rdquo; members.&lt;/p&gt;
&lt;p&gt;The best thing about this feature is the syntax. The word &amp;ldquo;friend&amp;rdquo; is just so expressive, and to use it is a simple one liner:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;Block&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;short&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;short&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;col&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;short&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_row&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;short&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;_col&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="k"&gt;friend&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;TheFriendClass&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;h2&gt;Use Case&lt;/h2&gt;
&lt;p&gt;After writing Swift code, and dealing with optionals, I really fell in love with this concept (Optionals). It eliminated null pointers and empty value issues in one go. Now that I am working on a C++ project; luckily, I found that &lt;a href="http://pocoproject.org"&gt;POCO&lt;/a&gt; has Optionals (and Nullables)! I started using this feature heavily right away.&lt;/p&gt;
&lt;p&gt;The biggest issue that I faced was that, in order to use &lt;code&gt;Poco::Nullable&lt;/code&gt;, the type had to have the default, no-argument constructor. This is because the &lt;code&gt;Nullable&lt;/code&gt; class had to always initialize the type memory to &lt;em&gt;something&lt;/em&gt;, even if it was null. Of course, pointers weren&amp;rsquo;t used, because if you want dynamic allocation, just go use &lt;code&gt;std::shared_ptr&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;What if the type you want to use with &lt;code&gt;Nullable&lt;/code&gt; doesn&amp;rsquo;t provide a default, no-argument constructor because it doesn&amp;rsquo;t make sense to have one? Yeah, it should be obvious now &amp;hellip; Friend dat class!&lt;/p&gt;
&lt;p&gt;By looking at the example above, and replacing &lt;code&gt;TheFriendClass&lt;/code&gt; with &lt;code&gt;Poco::Nullable&amp;lt;Block&amp;gt;&lt;/code&gt;, we safely expose the unreliable no-argument constructor only to the &lt;code&gt;Nullable&lt;/code&gt; class, so it can just initialize that memory to something. So, we are 100% certain now, that &lt;code&gt;Block&lt;/code&gt; objects can&amp;rsquo;t be initialized with the default constructor, unless they are safely within the &lt;code&gt;Nullable&lt;/code&gt; class, which won&amp;rsquo;t operate on the instantiated instance, anyway!&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Nullable&lt;/code&gt; implementation wouldn&amp;rsquo;t be possible without generics, and thankfully, C++ had that feature way back. I still get developers asking, &amp;ldquo;Are generics really useful?&amp;rdquo;. Yes. Yes they are.&lt;/p&gt;</content><category term="posts"></category><category term="friend"></category><category term="poco"></category><category term="pocoproject"></category><category term="class"></category><category term="c++"></category><category term="programming"></category><category term="tips"></category><category term="nullable"></category><category term="optional"></category><category term="template"></category><category term="safety"></category><category term="encapsulation"></category><category term="oop"></category><category term="design"></category></entry><entry><title>Basic C Programming</title><link href="https://mazyod.com/blog/2015/07/22/basic-c-programming/" rel="alternate"></link><published>2015-07-22T13:14:11+00:00</published><updated>2015-07-22T13:14:11+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-07-22:/blog/2015/07/22/basic-c-programming/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;After all this absence from my blog .. I just have to add an introduction! Well, since I stopped blogging a few months back, I was actually back home and for some reason, life is so easy going there, that I end up not able to work as effectively.. Weird …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;After all this absence from my blog .. I just have to add an introduction! Well, since I stopped blogging a few months back, I was actually back home and for some reason, life is so easy going there, that I end up not able to work as effectively.. Weird. Anyways, my travels have resumed now, and life is tougher than ever, yet I now have time to blog! :D&lt;/p&gt;
&lt;p&gt;Now, for an introduction about the actual topic&amp;hellip;&lt;/p&gt;
&lt;p&gt;C programming isn&amp;rsquo;t something every programmer stumbles upon anymore. Even though I am mainly an iOS developer, and have written tons of, technically speaking, C code mushed together with the ObjC code, I never realized the &amp;ldquo;proper&amp;rdquo; was to write a well structured C program until very recently.&lt;/p&gt;
&lt;h2&gt;Vitamin C Deficiency&lt;/h2&gt;
&lt;p&gt;One of the first things I miss when coming to the C world are classes. After learning and writing C++, ObjC, Python, and especially Java, classes are just this central part of my design. I dealt with top-level functions in some of those languages, but in very limited, and usually hackish ways.&lt;/p&gt;
&lt;p&gt;The lack of classes, meant lack of methods. Methods are insanely useful. Imagine not being able to write constructors for your classes. That will lead to so much boiler plate as you initialize all those properties whenever you instantiate a new instance of a class.&lt;/p&gt;
&lt;p&gt;Of course, the language lacks a lot of other useful features, like closures, generics, exceptions, .. etc, but today&amp;rsquo;s focus is on the classes.&lt;/p&gt;
&lt;h2&gt;Taking Supplements&lt;/h2&gt;
&lt;p&gt;For some reason, it never really clicked in my head till I recently started reading some well written C libraries .. Lack of classes is not that big of an issues, especially where methods are concerned. To emphasize on this point, take a look at &lt;a href="https://golang.org/"&gt;go by Google&lt;/a&gt;. It doesn&amp;rsquo;t have methods the way we are used to them in OOP languages.&lt;/p&gt;
&lt;p&gt;So, the realization was, and I feel so stupid for realizing this just now, is to simply do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Imagine you have a C++ class with a method&lt;/li&gt;
&lt;li&gt;Take that method to an outer scope&lt;/li&gt;
&lt;li&gt;Append the class name to the beginning, to add more context&lt;/li&gt;
&lt;li&gt;add a first parameter, which takes a pointer to an instance of that class&lt;/li&gt;
&lt;li&gt;Done!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you can see, we are simply doing some more manual work to what the compiler used to do for us automatically. When we call a method in C++, we can use &lt;code&gt;this&lt;/code&gt;, which is but the instance the method is called on, passed to the method automatically by the compiler. And, instead of using the nice &lt;code&gt;.&lt;/code&gt; syntax, we simple have a function prefixed with the class name.&lt;/p&gt;
&lt;p&gt;Here is a sample from the library I am working on:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;typedef&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nc"&gt;_DMGameMode&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;eGameType&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;gameType&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;eColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="n"&gt;eTimeLimit&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;timeLimit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DMGameMode&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DMGameMode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DMGameModeMake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;eGameType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DMGameMode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DMGameModeMakeSingle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;eColor&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DMGameModeDifficulty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DMGameMode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;DMGameModeMaxDepth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DMGameMode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I add &lt;code&gt;DM&lt;/code&gt; prefix for the lack of namespaces. Then, we have constructor like functions, and later methods that operator on an instance of that struct.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I knew that, for example, in ObjC method calls are translated to &lt;code&gt;objc_msgSend&lt;/code&gt; calls, and &lt;code&gt;self&lt;/code&gt;, &lt;code&gt;_cmd&lt;/code&gt; are passed in, but it didn&amp;rsquo;t click that this is how developers generally write C code. I was mostly concerned about using pointers, but it&amp;rsquo;s not that bad after all.&lt;/p&gt;</content><category term="posts"></category><category term="c"></category><category term="programming"></category><category term="development"></category><category term="snippets"></category><category term="clion"></category><category term="tips"></category></entry><entry><title>'HTTP Game Server: The Rewrite'</title><link href="https://mazyod.com/blog/2015/05/05/http-game-server-the-rewrite/" rel="alternate"></link><published>2015-05-05T18:03:22+00:00</published><updated>2015-05-05T18:03:22+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-05-05:/blog/2015/05/05/http-game-server-the-rewrite/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve stopped blogging for a while, and for no good reason, really. I will not make up any excuses, but will try to get the ball going once more.&lt;/p&gt;
&lt;h2&gt;The Past&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been blogging recently about my experience regarding building a game server on top of Google …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve stopped blogging for a while, and for no good reason, really. I will not make up any excuses, but will try to get the ball going once more.&lt;/p&gt;
&lt;h2&gt;The Past&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been blogging recently about my experience regarding building a game server on top of Google Appengine, and it was a nice journey. The game server was running pretty nicely, the tests were well integrated, and everything seemed to be on the right track. Except, when you think everything is going fine, nothing is.&lt;/p&gt;
&lt;p&gt;As of last month, I completely steered away from the Google AppEngine platform, and no longer maintaining that HTTP game server. I am glad (I think) the game hasn&amp;rsquo;t been shipped yet, so I can easily change gears without really affecting anything.&lt;/p&gt;
&lt;p&gt;But, what happened?&lt;/p&gt;
&lt;p&gt;As I started writing more and more client code, things quickly started getting ugly. In order to fix the client, I needed to update the backend. The backend already had tons of tests, so I needed to update those as well &amp;hellip; That&amp;rsquo;s when I lost the last thread of patience with Google AppEngine.&lt;/p&gt;
&lt;p&gt;To be honest, the issues isn&amp;rsquo;t really with Google AppEngine in itself, rather it was the language and the Restful API design.&lt;/p&gt;
&lt;h2&gt;What Now?&lt;/h2&gt;
&lt;p&gt;In order to write proper client networking code, I started utilizing the Poco C++ libraries. After using those libraries and tinkering around with other library components, I realized how amazing this library is, and how I can simply write the whole goddamn system on top of Poco, so it started.&lt;/p&gt;
&lt;p&gt;So, halfway through writing the client networking library code, I split the common networking part into a separate library, and started a new C++ server project that utilizes this shared library. Now, changing a single library will update both client and server!! NEAT!&lt;/p&gt;
&lt;p&gt;Not only that, but I also lost a shitload of time trying to implement a restful service in C++. After going through the implementation more and more, I kept refactoring till I finally reached a very minimal and functional client-server architecture!&lt;/p&gt;
&lt;p&gt;I reached this amazing design about 3 days ago, and I already have user registration, login, sessions, and matchmaking up and running. I had few small issues, but progress has never been faster. Finally, I can say that all that is left is grunt work of rolling out all the functionality, and then integrating it into the game.&lt;/p&gt;
&lt;h2&gt;More Guts and Gore&lt;/h2&gt;
&lt;p&gt;To share more insight on the design, here are some details:&lt;/p&gt;
&lt;h3&gt;What is Shared, Exactly?&lt;/h3&gt;
&lt;p&gt;The shared code is mostly entity classes that know how to serialize and unserialize themselves. This allows us to instantiate objects on the client/server then transport them and recreate them easily on the other side. Since it is a shared library, changing things will automatically reflect on both sides.&lt;/p&gt;
&lt;p&gt;This means we don&amp;rsquo;t even require a transport spec between the client and server, since the serialization happens in the shared library as well. &lt;/p&gt;
&lt;p&gt;Another amazing benefit is sharing actions and results. Now, whenever we want to perform an action from the client, the actions are all defined in the shared library, and so are the possible results. This allows the server to know what actions are possible, and the client to know what the possible results are, as well. Amazing.&lt;/p&gt;
&lt;h3&gt;How to Write Such Things?&lt;/h3&gt;
&lt;p&gt;This is C++, and it is not the most usable language. Actually, it is by far the most unusable language I care about. I had issues with templating, passing data around, but mostly, objects life time.&lt;/p&gt;
&lt;p&gt;After learning about the benefit of value types, and how they contribute to reducing overall system complexity, I dedicated myself to write as much value types as possible. I don&amp;rsquo;t really care at this point about efficiency, I care about correctness. There are some edge cases where pointers and dynamically allocated memory was necessary, and &lt;code&gt;std::shared_ptr&lt;/code&gt; was the star there, and I never had to manually manage any memory at all.&lt;/p&gt;
&lt;p&gt;To top it all off, I dedicated myself to writing a single threaded server. There was no need to deal with multithreading and the dreaded consequences that comes with it. Instead, even though the server is multithreaded, it dispatches all the work on a queue that gets consumed by a single thread. All the business logic runs exclusively on that thread.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Hopefully this will lead to a HTTP Game Server series rewrite, and if you are lucky, I really want to open source this and make it a starting point for all game developers out there.&lt;/p&gt;</content><category term="posts"></category><category term="api"></category><category term="appengine"></category><category term="backend"></category><category term="design"></category><category term="gae"></category><category term="game"></category><category term="google"></category><category term="http"></category><category term="kod"></category><category term="multiplayer"></category><category term="restful"></category><category term="scalable"></category><category term="server"></category><category term="turn-based"></category><category term="c++"></category></entry><entry><title>Benefits of Unit Tests</title><link href="https://mazyod.com/blog/2015/04/13/benefits-of-unit-tests/" rel="alternate"></link><published>2015-04-13T10:53:37+00:00</published><updated>2015-04-13T10:53:37+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-04-13:/blog/2015/04/13/benefits-of-unit-tests/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There is a very common problems among programmers that haven&amp;rsquo;t tried unit tests .. They don&amp;rsquo;t know how to start. Most of the programmers that I&amp;rsquo;ve met, including myself, had this problem, and the natural way to go about this is to buy a book and start …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There is a very common problems among programmers that haven&amp;rsquo;t tried unit tests .. They don&amp;rsquo;t know how to start. Most of the programmers that I&amp;rsquo;ve met, including myself, had this problem, and the natural way to go about this is to buy a book and start reading.&lt;/p&gt;
&lt;p&gt;Problem is, I had some &lt;a href="https://mazyod.com/blog/2014/03/23/diving-into-an-existing-project/"&gt;really bad experience with books on that topic&lt;/a&gt;, so did the people I met.&lt;/p&gt;
&lt;p&gt;Today, I have finally had enough unit test experience that allows me to explain how to go about this.&lt;/p&gt;
&lt;h2&gt;Clarity&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s be clear first &amp;hellip; There are many types of testing, unit testing, system testing, integration testing, black-box testing, white-box testing, &amp;hellip; etc. Make sure you read about all types of testing methodologies, because they will teach you &lt;strong&gt;what unit tests aren&amp;rsquo;t&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;To highlight some of the important topics here:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unit testing isn&amp;rsquo;t &lt;a href="http://en.wikipedia.org/wiki/Behavior-driven_development"&gt;BDD&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;BDD is writing high level tests that the business understands and can be expressed in terms of the system output. That means you don&amp;rsquo;t really care about the internal workings of the system as long as the correct output comes out.&lt;/p&gt;
&lt;p&gt;Integration tests, functional tests, system testing aren&amp;rsquo;t much different. They only differ in subtle ways, but they are all high level testing that usually doesn&amp;rsquo;t need knowledge of the internal system workings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What Unit Tests are&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Unit tests are tests that are written for every single part of your system. You test that your object contains certain properties, you test that invoking a certain method returns a certain result, and you even test the output signals generating from your system. It is a very low level rigorous testing.&lt;/p&gt;
&lt;h2&gt;Learnings&lt;/h2&gt;
&lt;p&gt;Now, here are the enlightenments I had while writing those tests&amp;hellip;&lt;/p&gt;
&lt;h3&gt;No Duplication&lt;/h3&gt;
&lt;p&gt;The fact that you have to test every single operation in your system makes you never want to write duplicate code .. ever. If you write duplicate code, you will duplicate your tests, and things will start looking shitty. I have a rule that, once you start copy pasting your unit tests, that means your program isn&amp;rsquo;t DRY enough, or you&amp;rsquo;re doing it all wrong.&lt;/p&gt;
&lt;p&gt;One reason you might end up writing duplicate tests is not necessarily duplicate code. You might be mixing BDD with TDD. Here is an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;operation&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;operation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that the component receives an operation that changes the behavior of this &lt;code&gt;Component&lt;/code&gt; class. How are you suppose to test this?&lt;/p&gt;
&lt;p&gt;If you are new to TDD, you might be tempted to instantiate a &lt;code&gt;Component&lt;/code&gt;, set the operation to something, and then make sure that operation performs properly. That is not proper TDD, because you will be duplicating the testing of the operation, which is external to this class!&lt;/p&gt;
&lt;p&gt;The test for this case is to simply pass a dummy operation with a mock object, and assert that when we call the &lt;code&gt;perform&lt;/code&gt; method, the mock object will be called:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Stub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;did_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="fm"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;did_call&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;true&lt;/span&gt;

&lt;span class="n"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stub&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;perform&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I hope the above example is clear. We are simply testing that if we pass an &lt;code&gt;operation&lt;/code&gt; to the &lt;code&gt;Component&lt;/code&gt;, the &lt;code&gt;Component&lt;/code&gt; will perform a call using that &lt;code&gt;operation&lt;/code&gt; when &lt;code&gt;perform&lt;/code&gt; is called.&lt;/p&gt;
&lt;p&gt;Fortunately, you are a passionate programmer, you can&amp;rsquo;t leave things the way they are! So, while writing unit tests for the system, that will be a perfect opportunity to find and eliminate duplication, and discover better ways to come up with abstractions.&lt;/p&gt;
&lt;h3&gt;Break Dependencies&lt;/h3&gt;
&lt;p&gt;Imagine if for you to write a test for a function that is the handler of a button click. So, on button clicked, you want to send an HTTP request, and schedule a notification (those are totally random things, but you might be doing something similar). Testing this function because almost impossible.&lt;/p&gt;
&lt;p&gt;You have to instantiate the HttpClient singleton, initialize the notification scheduler somehow in order to for the function to be tested properly .. That won&amp;rsquo;t do at all.&lt;/p&gt;
&lt;p&gt;The rule is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When writing unit tests, you must test each component in isolation. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Taking the previous example into consideration, we first need to make this function serve one purpose, and then test that alone. So, what we might have is another core component, completely separated from the UI, that receives a signal through some &lt;code&gt;NotificationCenter&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This way, all we have to do to test this function is make sure that it submits that notification! As for the other stuff that needs to happen, we can design it in the observing component.&lt;/p&gt;
&lt;p&gt;In this case, the component might have services registered to handle certain signals. So, there is an HTTPService that registers for that signal, and will send a request when that signal is received. Notice, that now we can test this HTTPService separately! The test is to make sure that when a signal is generated, the HTTPService attempts to send an HTTP request.&lt;/p&gt;
&lt;h3&gt;Catch Bug Early&lt;/h3&gt;
&lt;p&gt;Needless to say, that one of the toughest things we programmers go through is finding the origin of a bug, especially a semantic one. By unit testing, you can verify all your assumptions you are making by simply running the tests. That will help you catch bugs faster, because you are testing your changes at a micro level, before running them at a macro level.&lt;/p&gt;
&lt;p&gt;This is especially useful when you are writing C/C++ code, or in some scripting language, since it&amp;rsquo;s easy to make mistakes there. Something could easily slip by because of the extreme low-level/high-level programming.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Yeah, I am not gonna go through other obvious TDD benefits that people evangelize in books, since this post is all about practical advice that I actually experienced.&lt;/p&gt;</content><category term="posts"></category><category term="unit-test"></category><category term="snippet"></category><category term="code"></category><category term="programming"></category><category term="tdd"></category><category term="game"></category><category term="development"></category></entry><entry><title>POCO</title><link href="https://mazyod.com/blog/2015/04/09/poco/" rel="alternate"></link><published>2015-04-09T09:21:51+00:00</published><updated>2015-04-09T09:21:51+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-04-09:/blog/2015/04/09/poco/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve quit my job, and started doing lots of things I had in mind for years now. Point is, I am my own boss, and I would like to make stuff as perfect as possible.&lt;/p&gt;
&lt;p&gt;When you are working in a very small team (1) the number …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Recently, I&amp;rsquo;ve quit my job, and started doing lots of things I had in mind for years now. Point is, I am my own boss, and I would like to make stuff as perfect as possible.&lt;/p&gt;
&lt;p&gt;When you are working in a very small team (1) the number one priority for you becomes speed. It doesn&amp;rsquo;t matter anymore how robust your system is, how performant, how scalable &amp;hellip; etc, as long as you can get stuff done quickly and ship! Otherwise, welcome to the endless world of programming indulgence.&lt;/p&gt;
&lt;p&gt;With that said, you ultimately have requirements, which are the absolute rules you can never violate. You may be able to bend some, but some hard requirements just have to be accommodated.&lt;/p&gt;
&lt;p&gt;For my stuff, it has increasingly became apparent that I need to scale. I have verified the success of a few projects on the iOS platform in the local market, and now it&amp;rsquo;s either expanding internationally or to other platforms .. Hopefully, both!&lt;/p&gt;
&lt;p&gt;The number one language for mobile portability is without doubt C++. Apple uses C++ internally for loads of frameworks, so does Dropbox in their mobile app to share code, let&amp;rsquo;s not forget Realm, it basically C++ core, and last but not least .. Facebook&amp;rsquo;s fresh ComponentsKit. The C++ there actually goes beyond the internals, and is exposed in the interface!&lt;/p&gt;
&lt;p&gt;Bottom line, brace yourself for C++ programming if you plan on going cross platform. Good news, though. We&amp;rsquo;ll see why it isn&amp;rsquo;t so bad to write C++ code anymore.&lt;/p&gt;
&lt;h2&gt;What Was Wrong?&lt;/h2&gt;
&lt;p&gt;Back in the dark ages of pre-C++11 (C++x0), C++ was such a painful language with very limited features that made it very lacking when compared to newly created modern languages.&lt;/p&gt;
&lt;p&gt;I entered the C++ world by working at a game during my time at Sourcebits. The team, (which I hope they aren&amp;rsquo;t reading this now) including me, were &amp;ldquo;very behind&amp;rdquo; when it came to pure C++ programming. I mean, it was 2013, and the team didn&amp;rsquo;t know about the foreach syntax, lambdas, and other essential productivity features. These features were replaced by ruthless labor of basic design patterns. The code was horrible.&lt;/p&gt;
&lt;p&gt;I can&amp;rsquo;t really go into much details here, because to me, C++ was so horrible, I might&amp;rsquo;ve quit programming if it was the only choice. Hence, never programmed much in it during that time, as I sticked to working on tools and scripting with ObjC and Python.&lt;/p&gt;
&lt;p&gt;That all changed, because it had to.&lt;/p&gt;
&lt;h2&gt;What Changed?&lt;/h2&gt;
&lt;p&gt;After that experience, I was a bit more ready to use C++, since I&amp;rsquo;ve learned after that job about how C++11 changed everything. Downloading Cocos2d-X and learning from it&amp;rsquo;s opensource galore helped a lot in utilizing the new features.&lt;/p&gt;
&lt;p&gt;After about a year or so doing that, I wasn&amp;rsquo;t going anywhere. Dealing with Pointers, memory management, and other awefulness imposed by the Cocos2d-X engine for the sake of performance was really getting to me .. Remember the first thing I said in the introduction? Speed can&amp;rsquo;t be compromised!&lt;/p&gt;
&lt;p&gt;Meanwhile, Swift came out, and it taught me an insanely important lesson. Don&amp;rsquo;t fool yourself. Language matters, and productivity is greatly effected by choosing it, so choose carefully. Also, make sure it&amp;rsquo;s the language, and not that you are just a bad programmer.&lt;/p&gt;
&lt;p&gt;So, what happened was I realized I was a really bad C++ programmer. I approached C++ the same way I would approach ObjC or python, which was a huge source of pain. Classes where unnecessarily humongous, every class depended on every other class in the system, and yeah. I didn&amp;rsquo;t utilize any library.. !&lt;/p&gt;
&lt;h2&gt;The New C++&lt;/h2&gt;
&lt;p&gt;The new C++ to me is POCO.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/pocologo.png"&gt;&lt;/p&gt;
&lt;p&gt;By seeing POCO&amp;rsquo;s modular system and insane set of features, everything clicked. C++ is a great language, just need to utilize all available resources!&lt;/p&gt;
&lt;p&gt;It is very important to break every single component into small pieces. Attempt to make it generic, as well, so it doesn&amp;rsquo;t have many dependencies. Finally, utilize the hell out of the POCO library itself! The feature set it has and cross platform compatibility/portability is worthy of high praise. &lt;/p&gt;
&lt;h2&gt;But&amp;hellip;&lt;/h2&gt;
&lt;p&gt;I know, still, this is no silver bullet. Integrating C++ with other platform languages in order to leverage native frameworks is usually painful. NDK on android isn&amp;rsquo;t the most usable thing, nor C#&amp;rsquo;s dynamic plugin loader, but by investing the time upfront to put a solid build system, it could really payoff.&lt;/p&gt;
&lt;p&gt;Tools like Djinni, SWIG, &amp;hellip; etc help, probably, though I have yet to start using them.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll leave with this statement as food for thought:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Premature optimization in C++ is worst than being a really bad programmer.&lt;/p&gt;
&lt;/blockquote&gt;</content><category term="posts"></category><category term="poco"></category><category term="cpp"></category><category term="programming"></category><category term="library"></category><category term="compile"></category><category term="swift"></category><category term="optional"></category><category term="compare"></category><category term="portability"></category></entry><entry><title>Enlightenment</title><link href="https://mazyod.com/blog/2015/04/05/enlightenment/" rel="alternate"></link><published>2015-04-05T22:17:27+00:00</published><updated>2015-04-05T22:17:27+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-04-05:/blog/2015/04/05/enlightenment/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been blogging recently about Swift and SpriteKit, and that&amp;rsquo;s mostly eating up all my time, making me miss a blogging day, and also writing a &lt;a href="https://mazyod.com/blog/2015/04/02/braindump/"&gt;completely useless post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, to justify this, the previous three posts before that have been quite lengthy and informative, so it …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been blogging recently about Swift and SpriteKit, and that&amp;rsquo;s mostly eating up all my time, making me miss a blogging day, and also writing a &lt;a href="https://mazyod.com/blog/2015/04/02/braindump/"&gt;completely useless post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Now, to justify this, the previous three posts before that have been quite lengthy and informative, so it&amp;rsquo;s only natural that the bigger you are the harder you fall, lol.&lt;/p&gt;
&lt;p&gt;This post is just me trying to recover from the fail streak I&amp;rsquo;ve been having.&lt;/p&gt;
&lt;h2&gt;What Happened?&lt;/h2&gt;
&lt;p&gt;Actually, what &lt;strong&gt;didn&amp;rsquo;t&lt;/strong&gt; happen is I haven&amp;rsquo;t shipped my game yet. After three years of development on the side, it should have been released ages ago, and even new versions already out, but no &amp;hellip; That never happened.&lt;/p&gt;
&lt;p&gt;What did happen after that is I built a solid game prototype with my partner in two weeks. Two weeks vs Three years. And I am not talking about a throw away prototype, here. My partner suggested a throw away prototype, but I just went ahead and made it as solid as possible, with a simple yet rich architecture, that can easily evolve in the future.&lt;/p&gt;
&lt;h2&gt;How Is That Possible?&lt;/h2&gt;
&lt;p&gt;The infinitely long game was developed in Cocos2d-x using C++. It was initially built by a dump port of Objective-C code, and sustained all cocos2d-x&amp;rsquo;s updates &amp;hellip; It evolved into a really shitty beast. Adding new assets, moving things around, changing animations speeds, and all that still takes me a few days to get right, that is insane!&lt;/p&gt;
&lt;p&gt;Meanwhile, the new game prototype uses external tested components, and a very small footprint core engine that drives the game. Making new builds and testing takes &lt;em&gt;seconds&lt;/em&gt;. And of course, the language I am using is Swift. It is truly a reflection of its name.&lt;/p&gt;
&lt;h2&gt;What Now?&lt;/h2&gt;
&lt;p&gt;Now, it&amp;rsquo;s time to upgrade into a real game developer. &lt;/p&gt;
&lt;p&gt;Game development in itself is such a daunting and difficult task and doing it part time with hacks and workarounds isn&amp;rsquo;t sustainable. I did that a lot in the app development business, and it worked quite well, especially with a development cycle less than 1 month. Again, not in game development.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s time to actually architect each component separately, test it, and decide on the integrations. You&amp;rsquo;d probably be reading this and saying &amp;ldquo;But, of course!&amp;rdquo;. Well, I am the only programmer in the team, and buying in to such approach is a huge time investment, that requires significant solo experience, since you don&amp;rsquo;t have much people around to bounce ideas off of.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;In a nutshell, if you are doing game development for real, and looking to have that as you long term goal, &lt;strong&gt;STOP hacking and START building!&lt;/strong&gt;, and remember, it&amp;rsquo;s not a sprint, it&amp;rsquo;s a marathon.&lt;/p&gt;</content><category term="posts"></category><category term="rant"></category><category term="change"></category><category term="development"></category><category term="programming"></category><category term="process"></category><category term="game"></category><category term="code"></category></entry><entry><title>Brain.Dump()</title><link href="https://mazyod.com/blog/2015/04/02/braindump/" rel="alternate"></link><published>2015-04-02T21:21:43+00:00</published><updated>2015-04-02T21:21:43+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-04-02:/blog/2015/04/02/braindump/</id><summary type="html">&lt;ul&gt;
&lt;li&gt;So much freaking work to do, so little time&lt;/li&gt;
&lt;li&gt;Awake for more than 28 hours, and counting&lt;/li&gt;
&lt;li&gt;Game development in Swift is just amazing&lt;/li&gt;
&lt;li&gt;SpriteKit is crap, and crashes unpredictably&lt;/li&gt;
&lt;li&gt;We have an amazing prototype already! Yay!&lt;/li&gt;
&lt;li&gt;The component system built is a piece of art&lt;/li&gt;
&lt;li&gt;I must blog or …&lt;/li&gt;&lt;/ul&gt;</summary><content type="html">&lt;ul&gt;
&lt;li&gt;So much freaking work to do, so little time&lt;/li&gt;
&lt;li&gt;Awake for more than 28 hours, and counting&lt;/li&gt;
&lt;li&gt;Game development in Swift is just amazing&lt;/li&gt;
&lt;li&gt;SpriteKit is crap, and crashes unpredictably&lt;/li&gt;
&lt;li&gt;We have an amazing prototype already! Yay!&lt;/li&gt;
&lt;li&gt;The component system built is a piece of art&lt;/li&gt;
&lt;li&gt;I must blog or release the source someday&lt;/li&gt;
&lt;li&gt;Hopefully I can finish this last feature &lt;/li&gt;
&lt;li&gt;I think my brain is giving me 4 more hours&lt;/li&gt;
&lt;li&gt;Writing code in such state is amazing&lt;/li&gt;
&lt;li&gt;I see stars&lt;/li&gt;
&lt;li&gt;There is a cup of coffee fist bumping his friend&lt;/li&gt;
&lt;li&gt;What day is it today?&lt;/li&gt;
&lt;li&gt;I think I drank 4 cups of coffee today&lt;/li&gt;
&lt;li&gt;You know that feeling that you&amp;rsquo;re missing something&lt;/li&gt;
&lt;li&gt;Well, I feel I missed a meeting with the emperor&lt;/li&gt;
&lt;li&gt;Nothing makes sense anymore, but I did post!&lt;/li&gt;
&lt;li&gt;HabitRPG character will be pleased&lt;/li&gt;
&lt;li&gt;So will my wolf&lt;/li&gt;
&lt;li&gt;Princess Monanoke was an amazing movie&lt;/li&gt;
&lt;li&gt;It reminds me of Kiki&amp;rsquo;s delivery service&lt;/li&gt;
&lt;li&gt;Kiki is my X-roommate&amp;rsquo;s nickname, too&lt;/li&gt;
&lt;li&gt;He recently went to Bahrain&lt;/li&gt;
&lt;li&gt;Bahrain means &amp;ldquo;Two seas&amp;rdquo; in Arabic&lt;/li&gt;
&lt;li&gt;Only way to have to seas, is by a&lt;strong&gt;cc&lt;/strong&gt;elerating&lt;/li&gt;
&lt;li&gt;ha! I am not funny&lt;/li&gt;
&lt;li&gt;This hole thing was just a waste of your time, sorry&lt;/li&gt;
&lt;li&gt;no refunds available &lt;/li&gt;
&lt;li&gt;Hopefully you now realize how important time is&lt;/li&gt;
&lt;li&gt;Wow, I actually turned this into something useful&lt;/li&gt;
&lt;li&gt;I must stop lying to myself&lt;/li&gt;
&lt;li&gt;This will be the best SEO post of all time&lt;/li&gt;
&lt;li&gt;I wonder if I should stop typing ..&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="image" src="/images/tumblr_mu3ldtX6ZA1s4kxqxo1_500.gif"&gt;&lt;/p&gt;</content><category term="posts"></category><category term="rant"></category><category term="useless"></category><category term="waste"></category><category term="time"></category><category term="drunk"></category><category term="sleep"></category></entry><entry><title>Marry CircleCI to Hockey</title><link href="https://mazyod.com/blog/2015/03/26/marry-circleci-to-hockey/" rel="alternate"></link><published>2015-03-26T15:10:25+00:00</published><updated>2015-03-26T15:10:25+00:00</updated><author><name>Mazyad Alabduljaleel</name></author><id>tag:mazyod.com,2015-03-26:/blog/2015/03/26/marry-circleci-to-hockey/</id><summary type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;If I were to tell you, today we shall marry CircleCI to HockeyApp, who do you reckon would be the bride, and who would be the groom? Doesn&amp;rsquo;t really matter actually, as nowadays, that&amp;rsquo;s not the only allowed typed of marriages!&lt;/p&gt;
&lt;p&gt;Enough with the silly introduction, and …&lt;/p&gt;</summary><content type="html">&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;If I were to tell you, today we shall marry CircleCI to HockeyApp, who do you reckon would be the bride, and who would be the groom? Doesn&amp;rsquo;t really matter actually, as nowadays, that&amp;rsquo;s not the only allowed typed of marriages!&lt;/p&gt;
&lt;p&gt;Enough with the silly introduction, and onto the l00t.&lt;/p&gt;
&lt;h2&gt;Purpose&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://circleci.com/"&gt;CircleCI&lt;/a&gt; is an amazing service that provides continuous integration for various projects, including iOS projects. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Continuous integration&lt;/strong&gt; in its &amp;ldquo;final boss form&amp;rdquo; is a service that checkout the latest code, performs some automated changes and formatting, builds the product, runs automated tests on the product, performs post testing actions, and finally deploys the product.&lt;/p&gt;
&lt;p&gt;In a typical iOS project, the deployment phase is not necessarily deployment to the AppStore directly, but rather deploying to a distribution platform which can provide the latest builds to your QA team. For all we care, your QA team could be 🐵🐵🐵 that tap all over the screen and get bananas as a reward.&lt;/p&gt;
&lt;p&gt;Now, it could easily become a chore if you had to wait for the CI process to complete, before deploying to the distribution platform, hence the purpose of the article. Let CircleCI take care of that distribution.&lt;/p&gt;
&lt;h2&gt;Code Signing, Provisioning, and Archiving. Oh, My!&lt;/h2&gt;
&lt;p&gt;First of all, &lt;a href="https://github.com/infolens/CircleCI-iOS-TestFlight-Sample"&gt;take a look at this superb example&lt;/a&gt; of how things should work. The sample project shows how you can distribute TestFlight builds through CircleCI, so with a bit of tweaking and explaining on my end, you should be all set with minimal head-scratching.&lt;/p&gt;
&lt;h3&gt;Ground Work&lt;/h3&gt;
&lt;p&gt;Before doing anything else, if you want to commit to making builds on a server, you need to make sure the following checklist is accommodated:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Device UUIDs registered&lt;/li&gt;
&lt;li&gt;App ID for the product&lt;/li&gt;
&lt;li&gt;Ad Hoc Distribution Provisioning profile &lt;/li&gt;
&lt;li&gt;iOS Distribution certificate&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you&amp;rsquo;ve created those in &lt;a href="https://developer.apple.com/account/ios/profile/profileList.action?type=production"&gt;provisioning portal&lt;/a&gt;, you&amp;rsquo;re ready to move to next step.&lt;/p&gt;
&lt;h3&gt;Exporting&lt;/h3&gt;
&lt;p&gt;Now, we need to have the required files in one place, and we will use them in a second when we configure the repo. These files can be exported from your keychain on OSX:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Apple Worldwide Developer Relations Certification Authority
You can search for it in your &lt;code&gt;login&lt;/code&gt; keychain, and just export a &lt;code&gt;cer&lt;/code&gt; file, call it &lt;strong&gt;apple.cer&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhone Distribution certificate
Your iOS distribution certificate exported as a &lt;code&gt;cer&lt;/code&gt; file, call it &lt;strong&gt;dist.cer&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;iPhone Distribution private key
Your iOS distribution certificate exported as a &lt;code&gt;p12&lt;/code&gt; file, call it &lt;strong&gt;dist.p12&lt;/strong&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you export the private key, it will ask you for a password. Take not of that password, we will refer to it later.&lt;/p&gt;
&lt;p&gt;Now, either download your mobile provisioning profile file from the portal, or you can find it located at the following path:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;~/Library/MobileDevice/Provisioning&lt;span class="w"&gt; &lt;/span&gt;Profiles
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I use &lt;a href="https://github.com/chockenberry/Provisioning"&gt;the excellent quick look plugin&lt;/a&gt; to inspect the files.&lt;/p&gt;
&lt;p&gt;Anyway, once you have your hands on the profile, copy it &amp;ldquo;as is&amp;rdquo; to where ever you put the previous files.&lt;/p&gt;
&lt;h2&gt;Setting Up the Repo&lt;/h2&gt;
&lt;p&gt;Now we are ready to configure the git repository that will be checked out by circle ci. &lt;/p&gt;
&lt;p&gt;First, let me be clear:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here is where I made changes to what the github example has&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the github example, the developer prefers to run a bunch of custom scripts in order to generate an archive, process it, and upload it to test flight. In my case, I decided to simplify these steps as much as possible.&lt;/p&gt;
&lt;p&gt;So, with that out of the way, let&amp;rsquo;s see how can we make this happen:&lt;/p&gt;
&lt;h3&gt;Xcode&lt;/h3&gt;
&lt;p&gt;Some changes need to be made to the project itself, first. There must be a build configuration that has the code signing and provisioning profile set manually. In my case, I created a new build configuration, and set up the code signing and previously created provisioning profile:&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/code-signing-circle.png"&gt;&lt;/p&gt;
&lt;p&gt;You can use Release if you like, or call it Distribution, just make sure you take note of which build configuration is using the distribution identity.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This means we don&amp;rsquo;t need the &lt;code&gt;testflight.sh&lt;/code&gt; script in the github repo.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Environment&lt;/h3&gt;
&lt;p&gt;In order to upload your build to hockey, or any other service really, you need an access token. In order to secure the token and conveniently change it through UI, we will set it up through Circle CI project settings.&lt;/p&gt;
&lt;p&gt;Remember the exported private key &lt;code&gt;p12&lt;/code&gt; file that you password protected? Remember how I said to take note of the password? Here is where we will use that password, as well.&lt;/p&gt;
&lt;p&gt;Just go over to the project settings on circle CI, and set up the environment variables with &lt;code&gt;HOCKEYAPP_TOKEN&lt;/code&gt; and &lt;code&gt;KEY_PASSWORD&lt;/code&gt;. The hockeyapp token can be generated from the user account settings &lt;code&gt;-&amp;gt;&lt;/code&gt; API Tokens.&lt;/p&gt;
&lt;p&gt;Here is how it should look like (you don&amp;rsquo;t need all of those):&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="/images/circle-ci-environment.png"&gt;&lt;/p&gt;
&lt;h3&gt;Scripts&lt;/h3&gt;
&lt;p&gt;The scripts we will be using can be grabbed from &lt;a href="https://github.com/infolens/CircleCI-iOS-TestFlight-Sample/tree/master/scripts"&gt;the aforementioned github repo&lt;/a&gt;. We only need the &lt;code&gt;add-key.sh&lt;/code&gt; and &lt;code&gt;remove-key.sh&lt;/code&gt; scripts. Just grab them for now, and we will see where they go in a bit.&lt;/p&gt;
&lt;h3&gt;Circle.yml&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;circle.yml&lt;/code&gt; is &lt;a href="https://circleci.com/docs/configuration"&gt;a configuration file for circle CI&lt;/a&gt; that we need to setup. If you don&amp;rsquo;t already have that file, please create it at the root of your repository.&lt;/p&gt;
&lt;p&gt;Now, for the easiest possible solution, I use &lt;a href="https://github.com/nomad/shenzhen"&gt;Shenzhen&lt;/a&gt; for build and distribution. Notice the &lt;code&gt;-c Distribution&lt;/code&gt; flag is to choose the build configuration we already setup. &lt;/p&gt;
&lt;p&gt;You are free to use &lt;code&gt;xcodebuild&lt;/code&gt;, &lt;code&gt;xctool&lt;/code&gt;, or whatever you wish, but if you do that and still want to leverage Shenzhen distribution, you must also use &lt;code&gt;xcrun&lt;/code&gt; to get an ipa file. I will not cover that part, as I will be using shenzhen for everything.&lt;/p&gt;
&lt;p&gt;Shenzhen will need a hockeyapp token, and notice we will be using the environment variable we already set in the circle CI UI previously.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;pre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;sudo gem install shenzhen&lt;/span&gt;
&lt;span class="nt"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;override&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;./scripts/add-key.sh&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ipa build -c Distribution&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;./scripts/remove-key.sh&lt;/span&gt;
&lt;span class="nt"&gt;deployment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nt"&gt;hockey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;master&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="nt"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p p-Indicator"&gt;-&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l l-Scalar l-Scalar-Plain"&gt;ipa distribute:hockeyapp -m &amp;quot;circleci build&amp;quot; --token $HOCKEYAPP_TOKEN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;The Files&lt;/h3&gt;
&lt;p&gt;Now, copy all the files we covered in this post so you have the following hierarchy:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ROOT&lt;ul&gt;
&lt;li&gt;circle.yml&lt;/li&gt;
&lt;li&gt;scripts&lt;ul&gt;
&lt;li&gt;dist.cer&lt;/li&gt;
&lt;li&gt;dist.p12&lt;/li&gt;
&lt;li&gt;apple.cer&lt;/li&gt;
&lt;li&gt;add-key.sh&lt;/li&gt;
&lt;li&gt;remove-key.sh&lt;/li&gt;
&lt;li&gt;profile&lt;ul&gt;
&lt;li&gt;blah.mobileprovision&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Bringing It All Together&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Takes a Deep Breath&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;In a Nutshell&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So, we created all the certs, profiles, app ids, and configured the xcode project with those by adding a new build configuration. Then, dropped those files along some scripts into the repo, configured the circle.yml to generate a signed build, and uploaded the build using shenzhen.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Frankly, using shenzhen is a bit cumbersome since it has tons of dependencies on different distribution platforms, but it is just so darn simple. I will eventually move away from it, but for now it works well.&lt;/p&gt;
&lt;p&gt;There might be minor issues regarding ASCII stuff, just define the LC_CTYPE to utf-8 or something, unfortunately I don&amp;rsquo;t remember why I did that part.&lt;/p&gt;
&lt;p&gt;With all that done, you should be able to upload test through circle ci!&lt;/p&gt;</content><category term="posts"></category><category term="circleci"></category><category term="ci"></category><category term="continuous"></category><category term="integration"></category><category term="hockeyapp"></category><category term="puck"></category><category term="build"></category><category term="terminal"></category><category term="cli"></category><category term="bash"></category><category term="script"></category><category term="python"></category><category term="certificate"></category><category term="xcode"></category><category term="code-signing"></category><category term="provisioning"></category><category term="settings"></category><category term="distribution"></category><category term="ota"></category><category term="archive"></category></entry></feed>