<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog by Pulkit Goyal]]></title><description><![CDATA[I build mobile and web applications. Full Stack, Rails, React, Typescript, Kotlin, Swift]]></description><link>http://github.com/dylang/node-rss</link><generator>GatsbyJS</generator><lastBuildDate>Thu, 23 Jan 2025 06:33:23 GMT</lastBuildDate><item><title><![CDATA[ An Introduction to Exceptions in Elixir]]></title><description><![CDATA[Exceptions are a core aspect of programming, and a way to signal when something goes wrong with a program. An exception could result from a simple error, or your program might crash because of underlying constraints. Exceptions are not necessarily bad, though — they are fundamental to any working application.]]></description><link>https://pulkitgoyal.in/introduction-to-exception-in-elixir</link><guid isPermaLink="false">https://pulkitgoyal.in/introduction-to-exception-in-elixir</guid><pubDate>Tue, 01 Oct 2024 05:58:38 GMT</pubDate><content:encoded>&lt;p&gt;Exceptions are a core aspect of programming, and a way to signal when something goes wrong with a program. An exception could result from a simple error, or your program might crash because of underlying constraints. Exceptions are not necessarily bad, though - they are fundamental to any working application.&lt;/p&gt;
&lt;p&gt;Let’s see what our options are for handling exceptions in Elixir.&lt;/p&gt;
&lt;h2&gt;Raising Exceptions in Elixir&lt;/h2&gt;
&lt;p&gt;The Elixir (and Erlang) community is generally quite amenable to exceptions: “let it crash” is a common phrase. This is due, in part, to the excellent OTP primitives in Erlang/Elixir. The OTP primitives allow us to create supervisors that manage and restart processes (or a group of related processes) on failure.&lt;/p&gt;
&lt;p&gt;Exceptions can occur when something unexpected happens in your Elixir application. For example, division by zero raises an &lt;code class=&quot;language-text&quot;&gt;ArithmeticError&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;iex&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ArithmeticError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; bad argument &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; arithmetic &lt;span class=&quot;token attr-name&quot;&gt;expression:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token atom symbol&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    iex&lt;span class=&quot;token atom symbol&quot;&gt;:1&lt;/span&gt;: &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Exceptions can also be raised manually:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;iex&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; raise &lt;span class=&quot;token string&quot;&gt;&quot;BOOM&quot;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;RuntimeError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; BOOM
    iex&lt;span class=&quot;token atom symbol&quot;&gt;:1&lt;/span&gt;: &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By default, &lt;code class=&quot;language-text&quot;&gt;raise&lt;/code&gt; creates a &lt;code class=&quot;language-text&quot;&gt;RuntimeError&lt;/code&gt;. You can also raise other errors by using &lt;a href=&quot;https://hexdocs.pm/elixir/1.14/Kernel.html#raise/2&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;raise/2&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; Math &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; div&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; raise ArgumentError&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cannot divide by zero&quot;&lt;/span&gt;
	  a &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; b
	&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

iex&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ArgumentError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; cannot divide by zero
    iex&lt;span class=&quot;token atom symbol&quot;&gt;:4&lt;/span&gt;: Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
    iex&lt;span class=&quot;token atom symbol&quot;&gt;:3&lt;/span&gt;: &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A function call that doesn’t match a defined function  raises an &lt;code class=&quot;language-text&quot;&gt;ArgumentError&lt;/code&gt; by default:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; Math &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; div&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    a &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; b
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

iex&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FunctionClauseError&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; no function clause matching &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;

    The following arguments were given to Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;2:&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;# 1&lt;/span&gt;
        &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;# 2&lt;/span&gt;
        &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Handling Elixir Exceptions&lt;/h2&gt;
&lt;p&gt;Elixir provides the &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt;-&lt;code class=&quot;language-text&quot;&gt;rescue&lt;/code&gt; construct to handle exceptions:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  raise &lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
  e &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; RuntimeError &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inspect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This prints &lt;code class=&quot;language-text&quot;&gt;%RuntimeError{message: &amp;quot;foo&amp;quot;}&lt;/code&gt; in the console but doesn’t crash anything. Use this when you want to recover from exceptions in Elixir. It is also possible to skip binding the variable if it is unnecessary. For example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  raise &lt;span class=&quot;token string&quot;&gt;&quot;foo&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
  RuntimeError &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;puts&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;something bad happened&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In both of the above examples, we only &lt;code class=&quot;language-text&quot;&gt;rescue&lt;/code&gt; &lt;code class=&quot;language-text&quot;&gt;RuntimeError&lt;/code&gt;. If there is another error, it will still raise an exception. To rescue all exceptions raised inside the &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt; block, use the &lt;code class=&quot;language-text&quot;&gt;rescue&lt;/code&gt; without an error type, like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
  e &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;inspect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Running the above prints &lt;code class=&quot;language-text&quot;&gt;%ArithmeticError{message: &amp;quot;bad argument in arithmetic expression&amp;quot;}&lt;/code&gt;. If you want to perform different actions based on different exceptions, just add more clauses to the rescue branch.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
  RuntimeError &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;puts&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Runtime Error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  ArithmeticError &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;puts&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Arithmetic Error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  _e &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;puts&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Unknown error&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While rescuing all errors (without using a specific type) sounds tempting, it is a good practice to rely on specific exceptions because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You can perform different recovery tasks for different exceptions.&lt;/li&gt;
&lt;li&gt;It saves you from future breaking changes or programming errors going unnoticed.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For example, consider the below function:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; Config &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  	  contents &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; File&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      parse!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contents&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
      _e &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;some:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;default config&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It reads and parses a config file, returning the result. When written, it uses a generic clause to rescue from missing file-related errors. Let’s say that a while later, the input file gets corrupted somehow (e.g., a simple missing &lt;code class=&quot;language-text&quot;&gt;}&lt;/code&gt; or an extra &lt;code class=&quot;language-text&quot;&gt;,&lt;/code&gt; in a JSON file), and now there are parsing errors. Our function will still work without raising any issues, and we will be left guessing why it doesn’t work even though there’s an existing file.&lt;/p&gt;
&lt;p&gt;Another common practice in the Elixir community is to use &lt;code class=&quot;language-text&quot;&gt;ok&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;error&lt;/code&gt; tuples to signal errors instead of raising exceptions (for both internal and external libraries). So, instead of returning a simple &lt;code class=&quot;language-text&quot;&gt;result&lt;/code&gt; or raising an exception on an issue, a function in Elixir will return &lt;code class=&quot;language-text&quot;&gt;{:ok, result}&lt;/code&gt; on success and &lt;code class=&quot;language-text&quot;&gt;{:error, reason}&lt;/code&gt; on failure.&lt;/p&gt;
&lt;p&gt;This means that most of the time, a &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt; block will be preferable to try/rescue. For example, the above &lt;code class=&quot;language-text&quot;&gt;File.read!&lt;/code&gt; can be replaced by:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; File&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; contents&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; parse!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contents&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reason&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;some:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;default config&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In practice, you should reach out for &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;raise&lt;/code&gt; only in exceptional cases, never as a means of control flow. This is quite different from some other popular languages like Ruby or Java, where unexpected operations usually raise an error, then handle control flow for cases like non-existent files.&lt;/p&gt;
&lt;h2&gt;Re-raising Exceptions&lt;/h2&gt;
&lt;p&gt;Sometimes, we just want to know that there is an exception but not rescue from it - for example, to log an exception before allowing the process to crash or to wrap the exception into something more useful/understandable to the user.&lt;/p&gt;
&lt;p&gt;This is where &lt;code class=&quot;language-text&quot;&gt;reraise&lt;/code&gt; can be helpful, as it preserves an exception’s existing stack trace:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
  e &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;puts&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Exception&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;format&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; __STACKTRACE__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    reraise e&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; __STACKTRACE__
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, we use the &lt;code class=&quot;language-text&quot;&gt;__STACKTRACE__&lt;/code&gt; to retrieve the original trace of the exception, including its origin and the full call stack.&lt;/p&gt;
&lt;p&gt;In a real-world application, you might use this to report a metric/send exception to a third-party exception tracking service, or log something informative to a third-party logging service. For example, &lt;a href=&quot;https://appsignal.com/users/sign_up&quot;&gt;you might send telemetry data to AppSignal&lt;/a&gt; under these circumstances.&lt;/p&gt;
&lt;p&gt;In addition, it is also common practice to have custom exceptions for cases where unexpected things happen in libraries. &lt;code class=&quot;language-text&quot;&gt;reraise/3&lt;/code&gt; can be useful here:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; DivisionByZeroError &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;defexception&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; Math &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; div&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      a &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; b
    &lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
      e &lt;span class=&quot;token operator&quot;&gt;in&lt;/span&gt; ArithmeticError &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        reraise DivisionByZeroError&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;message:&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; __STACKTRACE__
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now using &lt;code class=&quot;language-text&quot;&gt;Math.div(1, 0)&lt;/code&gt; will raise a &lt;code class=&quot;language-text&quot;&gt;DivisionByZeroError&lt;/code&gt; instead of a generic &lt;code class=&quot;language-text&quot;&gt;ArithmeticError&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Rescue And Catch in Elixir&lt;/h2&gt;
&lt;p&gt;In Elixir, &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;raise&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;rescue&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;throw&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;catch&lt;/code&gt; are different. &lt;code class=&quot;language-text&quot;&gt;raise&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;rescue&lt;/code&gt; are used for exception handling, whereas &lt;code class=&quot;language-text&quot;&gt;throw&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;catch&lt;/code&gt; are used for control flow.&lt;/p&gt;
&lt;p&gt;A &lt;code class=&quot;language-text&quot;&gt;throw&lt;/code&gt; stops code execution (much like a &lt;code class=&quot;language-text&quot;&gt;return&lt;/code&gt; - but with the difference that it bubbles up until a &lt;code class=&quot;language-text&quot;&gt;catch&lt;/code&gt; is encountered). It is rarely needed and is only an escape hatch to be used when an API doesn’t provide an option to do something.&lt;/p&gt;
&lt;p&gt;For example, let’s say that there’s an API that produces numbers and invokes a callback:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; Producer &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; produce&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;callback&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    Enum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;each&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; callback&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;(This is just an example. Assume that with the real API, it is much more expensive to produce each number, and it produces an infinite list of numbers.)&lt;/p&gt;
&lt;p&gt;We want to find the first number divisible by 13, since we don’t have any other apparent way of finding that number and stopping the production at that point. Let’s see how we can use &lt;code class=&quot;language-text&quot;&gt;throw&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;catch&lt;/code&gt; to do this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  Producer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;produce&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; rem&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      throw&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt;
  x &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; IO&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;puts&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;First number divisible by 13 is &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;x&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’s worth stating that this is a bit of a contrived case, and most good APIs are designed in such a way that you never need to reach out for &lt;code class=&quot;language-text&quot;&gt;throw&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;catch&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;After and Else Blocks in Elixir&lt;/h2&gt;
&lt;p&gt;You can use &lt;code class=&quot;language-text&quot;&gt;after&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt; blocks with all &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt; blocks. An &lt;code class=&quot;language-text&quot;&gt;after&lt;/code&gt; block is called after processing all other blocks related to the &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt;, regardless of whether any of the blocks raised an error. This is useful for performing any required clean-up operations.&lt;/p&gt;
&lt;p&gt;For example, the below code creates a new producer and makes some results. If there’s an error during production, it will raise an exception. But the &lt;code class=&quot;language-text&quot;&gt;after&lt;/code&gt; block ensures that the producer is still disposed of regardless.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;producer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Producer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;new
&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	Producer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;produce!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;producer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;after&lt;/span&gt;
  Producer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dispose&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;producer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On the other hand, an &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt; block is called only if the &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt; block is completed without raising an error. The &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt; block receives the &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt; block’s result. The return value from the &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt; block is the final return value of the &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt;. For example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  File&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;read!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;/path/to/file&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt;
  File&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Error &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:not_found&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;a&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:a&lt;/span&gt;
  _other &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:other&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In the above code, if the file exists with content &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;, the result will be &lt;code class=&quot;language-text&quot;&gt;:a&lt;/code&gt;. The result is &lt;code class=&quot;language-text&quot;&gt;:not_found&lt;/code&gt; if the file doesn’t exist, and&lt;code class=&quot;language-text&quot;&gt;:other&lt;/code&gt; if the content is anything else.&lt;/p&gt;
&lt;h2&gt;Exceptions and Processes&lt;/h2&gt;
&lt;p&gt;No discussion about Elixir exceptions is complete without examining their impact on processes. Any unhandled exceptions cause a process to exit.&lt;/p&gt;
&lt;p&gt;With this in mind, let’s revisit the “let it crash” strategy. If we don’t handle an exception from a process, it will crash. This is good in a way because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Since all processes are separate from each other, an exception or unhandled crash from one process can never affect the state of another process.&lt;/li&gt;
&lt;li&gt;In most sophisticated Elixir applications, all the processes run under a supervision tree. So, an unexpected exit will restart the process (depending on the supervision strategy) and any linked processes it depends on with a clean slate.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In most cases, intermittent issues will resolve themselves in the next run. This is much easier (and usually also cleaner) than handling each failure separately and performing a recovery step.&lt;/p&gt;
&lt;p&gt;If you want to learn more about supervisors, I suggest the &lt;a href=&quot;https://elixir-lang.org/getting-started/mix-otp/supervisor-and-application.html&quot;&gt;official Elixir Supervisor and Application guide&lt;/a&gt; as a great starting point.&lt;/p&gt;
&lt;h2&gt;Monitoring Exceptions&lt;/h2&gt;
&lt;p&gt;As we’ve seen, exceptions are a fundamental part of any application. Handling them is good, but sometimes, letting them crash a process is even better.
But in all cases, it is better to monitor exceptions happening in the real world so that you can take action if there’s something concerning (for example, a developer error that crashes an app).&lt;/p&gt;
&lt;p&gt;This is where &lt;a href=&quot;https://www.appsignal.com/elixir&quot;&gt;AppSignal for Elixir&lt;/a&gt; can help. Once set up, it automatically records all errors and can also trigger alerts based on predefined conditions&lt;/p&gt;
&lt;p&gt;Here’s an example of an individual error you can get to from the “Errors” -&gt; “Issue list” in AppSignal for debugging:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_pad,w_800/v1737612903/monitoring_exception.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Check out the &lt;a href=&quot;https://docs.appsignal.com/elixir/installation.html&quot;&gt;AppSignal for Elixir installation guide&lt;/a&gt; to get started.&lt;/p&gt;
&lt;h2&gt;Wrapping Up&lt;/h2&gt;
&lt;p&gt;In this post, we explored how errors are treated in Elixir and how to recover from them. We also saw that sometimes it is better to just let a process crash and be restarted through the supervisor than to manually perform recovery steps for all possible exceptions.&lt;/p&gt;
&lt;p&gt;Elixir’s API makes a clear distinction between functions that raise an exception (usually ending in &lt;code class=&quot;language-text&quot;&gt;!&lt;/code&gt;) and functions that return a success/error tuple. If you are a library author, it is better to provide both options for users.&lt;/p&gt;
&lt;p&gt;Reach out for the tuple-based methods when you need to handle error cases separately. In Elixir, we rarely use &lt;code class=&quot;language-text&quot;&gt;try&lt;/code&gt; blocks for control flow -  the &lt;code class=&quot;language-text&quot;&gt;!&lt;/code&gt; functions are for when we want a process to crash on unexpected events.&lt;/p&gt;
&lt;p&gt;Until next time, happy coding!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[An Introduction to Mocking Tools for Elixir]]></title><description><![CDATA[A well-written test suite is a big part of any successful application. But let's say you rely on an external dependency for some parts of your app (for example, an external API for fetching user information). It then becomes important to mock that dependency in the test suite to prevent external API calls during testing or to test specific behavior.]]></description><link>https://pulkitgoyal.inmocking-tools-elixir</link><guid isPermaLink="false">https://pulkitgoyal.inmocking-tools-elixir</guid><pubDate>Wed, 07 Jun 2023 04:57:14 GMT</pubDate><content:encoded>&lt;p&gt;A well-written test suite is a big part of any successful application.
But let’s say you rely on an external dependency for some parts of your app (for example, an external API for fetching user information). It then becomes important to mock that dependency in the test suite to prevent external API calls during testing or to test specific behavior.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_780/v1686114515/mocking_tools_elixir.png&quot; alt=&quot;Mocking Tools in Elixir&quot; title=&quot;Mocking Tools in Elixir&quot;&gt;&lt;/p&gt;
&lt;p&gt;Several frameworks help reduce the boilerplate and make mocking safe for Elixir tests.
We will explore some of the major mocking tools available in this post.
Let’s get started!&lt;/p&gt;
&lt;h2&gt;Test Without Mocking Tools in Elixir&lt;/h2&gt;
&lt;p&gt;Depending on the scope of your tests, you might not need to use any external mocking tools.
You can use test stubs or roll your own server instead.&lt;/p&gt;
&lt;h3&gt;Test Stubs&lt;/h3&gt;
&lt;p&gt;The simplest way to stub/mock out some parts from a function call is to pass around modules that do the actual work and use a different implementation during the tests.&lt;/p&gt;
&lt;p&gt;Let’s say you need to access the GitHub API to fetch a user’s profile with an implementation like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPI &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;username&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        parse&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reason&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reason&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We know the implementation relies on HTTPoison to make actual calls to the GitHub API.
To mock it during tests, we can update the implementation to pass around an &lt;code class=&quot;language-text&quot;&gt;http_client&lt;/code&gt; and use a different one during tests.
Something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPI &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; http_client &lt;span class=&quot;token operator&quot;&gt;\\&lt;/span&gt; HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; http_client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;username&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;#... handle results&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This approach aligns with the &lt;a href=&quot;https://www.infoworld.com/article/3136224/demystifying-the-law-of-demeter-principle.html&quot;&gt;Law of Demeter&lt;/a&gt; - a module should only have a limited knowledge of the objects (in this case, the HTTP client) it works on.
This approach is nice because it decouples the &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; module from the HTTP client implementation.
Our &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; users can continue using it in the same way.
But for unit-testing &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt;, we can pass in our custom &lt;code class=&quot;language-text&quot;&gt;http_client&lt;/code&gt; that returns just the results we need.
For example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPITest &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubHTTPClientUser &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Response&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;status_code:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;body:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;~s&amp;lt;{&quot;login&quot;: &quot;octocat&quot;}&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Error&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Not Found&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  test &lt;span class=&quot;token string&quot;&gt;&quot;can fetch a user&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;login:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GithubHTTPClientUser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  test &lt;span class=&quot;token string&quot;&gt;&quot;handles errors when fetching a user&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Error&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unknown&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GithubHTTPClientUser&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That works, and you have 100% test coverage! 🎉
But as you can already imagine, while this works well for small tests, it will become increasingly difficult to manage if our &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; class grows to include other features.
Another similar strategy is to use application configuration instead of passing around the client modules.
This is especially useful when you need to mock out the API from all the tests, even when this API is called from other internal modules.
We can update our code to this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# github_api.ex&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPI &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token attribute variable&quot;&gt;@http_client&lt;/span&gt; Application&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;compile_env&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; Keyword&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:http_client&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token attribute variable&quot;&gt;@http_client&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;username&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;#... handle results&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# test/support/mock_github_http_client.ex&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MockGithubHTTPClient &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ... All mock implementations here&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# config/test.exs&lt;/span&gt;
config &lt;span class=&quot;token atom symbol&quot;&gt;:my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;http_client:&lt;/span&gt; MockGithubHTTPClient&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The good thing is that you don’t need to worry about mocking out &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; calls in each test case by manually passing the HTTP client.
This is especially important when the actual API calls are nested inside other functions.
For example, if your application automatically fetches the user from GitHub after a new account is created, you don’t need to mock &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; everywhere you create new users.
But it still has the same disadvantages as the previous strategy. Plus, the mocks must be generic enough to be used throughout the test suite.&lt;/p&gt;
&lt;h3&gt;Roll Your Own Server&lt;/h3&gt;
&lt;p&gt;This one is interesting.
Since &lt;a href=&quot;https://github.com/elixir-plug/plug_cowboy&quot;&gt;plug and cowboy&lt;/a&gt; make it really easy to roll out an HTTP server, instead of mocking out the HTTP Client, we can start our own server during tests and respond with stubs instead.&lt;/p&gt;
&lt;p&gt;If you want to learn more, check out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/flatiron-labs/rolling-your-own-mock-server-for-testing-in-elixir-2cdb5ccdd1a0&quot;&gt;Testing External Web Requests in Elixir? Roll Your Own Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.appsignal.com/2021/06/22/how-to-test-websocket-clients-in-elixir-with-a-mock-server.html&quot;&gt;How to Test WebSocket Clients in Elixir with a Mock Server&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the strategies discussed above, quite a bit of boilerplate is involved in setting up the tests.
And if you need a way to validate that a specific function was called with specific arguments, you need to do additional work.
If you have just a small external dependency that you need to mock out, this might work well for you. But if there are complex edge cases and branches that you need to test out, mocking tools can help to simplify the complexity of writing and maintaining those mocks in the long run.&lt;/p&gt;
&lt;h2&gt;Elixir Mocking Tools&lt;/h2&gt;
&lt;h2&gt;Mock&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jjh42/mock&quot;&gt;Mock&lt;/a&gt; is the first result you will see when searching “Elixir Mock”, and is a wrapper around Erlang’s &lt;a href=&quot;https://github.com/eproxus/meck&quot;&gt;meck&lt;/a&gt; that provides easy mocking macros for Elixir.&lt;/p&gt;
&lt;p&gt;With &lt;code class=&quot;language-text&quot;&gt;Mock&lt;/code&gt;, you can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Replace any module at will during tests to change return values.&lt;/li&gt;
&lt;li&gt;Pass through to the original function.&lt;/li&gt;
&lt;li&gt;Validate calls to the mocked functions.&lt;/li&gt;
&lt;li&gt;Check the complete call history, including arguments and results for each call.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is a very powerful tool, and the macro &lt;a href=&quot;https://github.com/jjh42/mock#with_mock---Mocking-a-single-module&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;with_mock&lt;/code&gt;&lt;/a&gt; makes mocking during tests really easy.
Let’s see how we can rewrite our test case to validate &lt;code class=&quot;language-text&quot;&gt;GithubAPI.fetch_user&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPITest &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# This is important, Mock doesn&apos;t work with async tests!&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Case&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Mock

  test &lt;span class=&quot;token string&quot;&gt;&quot;can fetch a user&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    with_mock HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;get:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; _url &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;status_code:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;body:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;~s({&quot;login&quot;: &quot;octocat&quot;})&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;login:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      assert_called HTTPotion&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Very sleek. There’s no need to define and pass boilerplate modules around or fiddle with the config just for tests.
Our implementation is completely isolated from the test code and needs no special changes to fit the tests.
And if we need to validate that a function was called with specific arguments, we can do that as well with &lt;code class=&quot;language-text&quot;&gt;assert_called&lt;/code&gt;.
One of the major drawbacks of this strategy is that you cannot use it with &lt;code class=&quot;language-text&quot;&gt;async&lt;/code&gt; tests.
It doesn’t prevent you from using Mock inside asynchronous tests, so this can lead to hard-to-track flaky tests.
In my opinion, Mock works well for certain types of tests.
I usually find myself reaching for it when we need to mock external libraries that we have no control over.
For example, let’s say we use an &lt;a href=&quot;https://github.com/edgurgel/tentacat&quot;&gt;external library&lt;/a&gt; to fetch a user’s GitHub profile instead of our custom &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt;.
Something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; create_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;github_username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  Tentacat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Users&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;find&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Tentacat&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;new&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; github_username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# ... create user&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# ... handle error&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, if we dig into the library’s documentation/code, we can see that it uses HTTPoison to make the eventual request to the API. But we don’t want to - or have a way to - customize that client just for tests.
Here, &lt;code class=&quot;language-text&quot;&gt;with_mock&lt;/code&gt; can easily help mock out that call so that we don’t request the API.
In fact, a much better approach, in this case, is to use &lt;code class=&quot;language-text&quot;&gt;with_mock&lt;/code&gt; to simply mock out the &lt;code class=&quot;language-text&quot;&gt;Tentacat.Users.find&lt;/code&gt; call altogether.
That saves you from having to dig into the library’s internal code (which can change with any update) and relying solely on mocking out its public interface.&lt;/p&gt;
&lt;h2&gt;Mox&lt;/h2&gt;
&lt;p&gt;We saw above how easy it is to mock some methods out and have our tests pass.
We sprinkle these calls in a few places to mock &lt;code class=&quot;language-text&quot;&gt;HTTPoison&lt;/code&gt;, and we are done.
But what if we later decide that &lt;code class=&quot;language-text&quot;&gt;HTTPoison&lt;/code&gt; isn’t fast enough and want to switch to another HTTP client implementation? Suddenly, all our tests fail - we have to go back and fix them up.
Even worse, what if the API for &lt;code class=&quot;language-text&quot;&gt;HTTPoison&lt;/code&gt; changes, but since we mocked it out, our tests never failed, and we pushed something that didn’t work to production?&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dashbitco/mox&quot;&gt;Mox&lt;/a&gt; helps get around these issues by ensuring explicit contracts.
Read &lt;a href=&quot;https://dashbit.co/blog/mocks-and-explicit-contracts&quot;&gt;Mocks and Explicit Contracts&lt;/a&gt; for more details.
Using our &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; example above, this is how we need to set up the tests with Mox.&lt;/p&gt;
&lt;h3&gt;Mock the External Client&lt;/h3&gt;
&lt;p&gt;We first convert our API client into a &lt;a href=&quot;https://hexdocs.pm/elixir/1.4.5/behaviours.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Behaviour&lt;/code&gt;&lt;/a&gt; to define the explicit contract the API client should follow.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# lib/my_app/github/api.ex&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token attribute variable&quot;&gt;@callback&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Error&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; impl&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; impl&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; Application&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_env&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GtihubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HTTP&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, we define the API Client that makes the actual requests to fetch the user.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# lib/my_app/github/http.ex&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HTTP &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token attribute variable&quot;&gt;@behaviour&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI

  &lt;span class=&quot;token attribute variable&quot;&gt;@impl&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;username&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;username&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Parse response here...&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;# Handle error here...&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reason&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, in our test helper, we define a mock &lt;code class=&quot;language-text&quot;&gt;MyApp.GithubAPI.Mock&lt;/code&gt; for the API and set it in our application environment.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# test/test_helper.exs&lt;/span&gt;
Mox&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;defmock&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mock&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;for:&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
Application&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;put_env&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:my_app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mock&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can refactor the test case to use &lt;code class=&quot;language-text&quot;&gt;Mox&lt;/code&gt; for mocking out the call to the external API:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# test/my_app/github/api_test.exs&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPITest &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Case&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Mox

  setup &lt;span class=&quot;token atom symbol&quot;&gt;:verify_on_exit&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;

  test &lt;span class=&quot;token string&quot;&gt;&quot;can fetch a user&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mock
    &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; expect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:fetch_user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;login:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    assert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;login:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are several interesting aspects to the above code. Let’s break it down.&lt;/p&gt;
&lt;p&gt;First, we use the &lt;code class=&quot;language-text&quot;&gt;expect&lt;/code&gt; function to define an expectation on the API. We expect a single call to &lt;code class=&quot;language-text&quot;&gt;fetch_user&lt;/code&gt; with the argument &lt;code class=&quot;language-text&quot;&gt;&amp;quot;octocat&amp;quot;&lt;/code&gt;, and we mock it to return a &lt;code class=&quot;language-text&quot;&gt;{:ok, %Github.User{}}&lt;/code&gt; tuple.
Now, when we call the &lt;code class=&quot;language-text&quot;&gt;GithubAPI.fetch_user/1&lt;/code&gt; in the test, it will reach for that mocked expectation instead of the default implementation.
Thus, we can safely assert the result of the call without making calls to the actual API.
The &lt;code class=&quot;language-text&quot;&gt;verify_on_exit!&lt;/code&gt; function as &lt;code class=&quot;language-text&quot;&gt;setup&lt;/code&gt; ensures that  all expectations defined with &lt;code class=&quot;language-text&quot;&gt;expect&lt;/code&gt; are fulfilled when a test case finishes.
So if we define an expectation on &lt;code class=&quot;language-text&quot;&gt;fetch_user&lt;/code&gt; and it isn’t actually called (e.g., if the implementation changes later), we see the test fail.
Finally, notice that we don’t need to mark the test as non-async here.
That’s because Mox supports mocking inside async tests. So you can define two completely different mocks in two test cases, and they will both pass, even if they run simultaneously.
You can also define a global stub to avoid providing mocks in every test.
This is useful if your client is being used in several places and you don’t want to explicitly define and validate expectations everywhere.
To do this, just update your ExUnit case template:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Case &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CaseTemplate

  setup _context &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    Mox&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stub_with&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mock&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Stub&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And create a stub with some static results:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Stub &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token attribute variable&quot;&gt;@behaviour&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI

  &lt;span class=&quot;token attribute variable&quot;&gt;@impl&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;login:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now every time you &lt;code class=&quot;language-text&quot;&gt;use MyApp.Case&lt;/code&gt; in a test case, you don’t need to manually mock calls to &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; - they will automatically be forwarded to the stubbed module.
This works well when you have calls to the &lt;code class=&quot;language-text&quot;&gt;GithubAPI&lt;/code&gt; that you will hit across several test suites.
With a stub, you can be sure that such calls always return a specific and stable response without having to mock them out manually.&lt;/p&gt;
&lt;h3&gt;Test the External Client&lt;/h3&gt;
&lt;p&gt;If you are following along closely, you will notice that we didn’t actually test the &lt;code class=&quot;language-text&quot;&gt;MyApp.Github.HTTP&lt;/code&gt; module at all.
Don’t worry, we won’t leave it untested.
But the recommended way here is to do integration tests instead of using mocking at that level.
We will also configure it so that these tests don’t run when you run the full test suite.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# test/my_app/github/http_test.exs&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;HTTPTest &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Case&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# All tests will ping the API&lt;/span&gt;
  &lt;span class=&quot;token attribute variable&quot;&gt;@moduletag&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:github_api&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# Write your tests here&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# test/test_helper.exs&lt;/span&gt;
ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configure &lt;span class=&quot;token attr-name&quot;&gt;exclude:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:github_api&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next step is to set up your CI pipeline to ensure that these tests run when required.
For example, you can configure it to run on all pull requests targeting &lt;code class=&quot;language-text&quot;&gt;main&lt;/code&gt; to avoid reaching the external API on every commit. You can also check that your CI pipeline runs before anything is merged to the main branch.
To do this, use the &lt;code class=&quot;language-text&quot;&gt;include&lt;/code&gt; command line flag when running &lt;code class=&quot;language-text&quot;&gt;mix test&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;mix test &lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;include github_api&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are several pros to the above strategy. You are now testing all parts of the application, including the calls to the external API (this part is not exactly dependent on Mox, but since we mocked out a significant part of our HTTP client, we must test it separately).
We can also define global stubs, specific mocks, and expectations only when required, which makes most of our test- suite very clean and concise.
The major drawback is that it requires quite some setup - you need a new &lt;code class=&quot;language-text&quot;&gt;behaviour&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;@callbacks&lt;/code&gt; for each public method you want to mock out. You have to implement that &lt;code class=&quot;language-text&quot;&gt;behaviour&lt;/code&gt; inside your module and finally set up &lt;code class=&quot;language-text&quot;&gt;Mox&lt;/code&gt; to mock out that implementation during tests.&lt;/p&gt;
&lt;p&gt;And since we are now reaching the external API, the tests can be flaky, depending on the API’s availability.&lt;/p&gt;
&lt;h2&gt;Mimic&lt;/h2&gt;
&lt;p&gt;If you are used to &lt;a href=&quot;https://github.com/freerange/mocha&quot;&gt;Mocha&lt;/a&gt; for other languages, you can check out &lt;a href=&quot;https://github.com/edgurgel/mimic&quot;&gt;Mimic&lt;/a&gt;.
It lets you define stubs and expectations during tests by keeping track of the stubbed module in an ETS table.
It also maintains separate mocks for each process, so you can continue using async tests.
It’s a great alternative to &lt;a href=&quot;https://github.com/jjh42/mock&quot;&gt;Mock&lt;/a&gt; - but that also means the same caveats apply - be careful about what you mock.
Here’s what a sample test looks like with Mimic:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# test_helper.exs&lt;/span&gt;
Mmimc&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;copy&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# github_api_test.exs&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; GithubAPITest &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; ExUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Case&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;async:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; Mimic

  test &lt;span class=&quot;token string&quot;&gt;&quot;can fetch a user&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://api.github.com/users/octocat&quot;&lt;/span&gt;
    expect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;status_code:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;body:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;~s({&quot;login&quot;: &quot;octocat&quot;})&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    assert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Github&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;User&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;login:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; GithubAPI&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fetch_user&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;octocat&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;expect/3&lt;/code&gt; automatically verifies that the function is called.
And all &lt;code class=&quot;language-text&quot;&gt;expect&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;stub&lt;/code&gt; calls can be &lt;a href=&quot;https://github.com/edgurgel/mimic#using&quot;&gt;chained&lt;/a&gt;, which makes up clear mocking code.&lt;/p&gt;
&lt;h2&gt;Use Mocking Right for Your Elixir App&lt;/h2&gt;
&lt;p&gt;Mocking is an important and necessary part of any test suite.
But the thing to remember about mocking is that it is imperative to do it right.&lt;/p&gt;
&lt;p&gt;For example, it might be tempting to mock out an internal API to quickly simulate &lt;em&gt;something&lt;/em&gt; for a test.
And yes, it works for quick unit tests.
But then, someone else (or maybe you) comes along a while later and changes that &lt;em&gt;something&lt;/em&gt; that you mocked earlier.&lt;/p&gt;
&lt;p&gt;Your tests still pass since they use the mocked value. But in practice, the thing is now broken, and it will be caught much later in the feedback loop (or worse still, be shipped to the user as-is).&lt;/p&gt;
&lt;h2&gt;Wrap Up&lt;/h2&gt;
&lt;p&gt;In this post, we explored several mocking strategies you can use in Elixir tests.
The safest one, and the one you should consider using first, is &lt;code class=&quot;language-text&quot;&gt;Mox&lt;/code&gt; since it forces mocked modules to have a defined behavior. Mox can therefore catch issues that arise from API changes during compilation.&lt;/p&gt;
&lt;p&gt;Reach out for &lt;code class=&quot;language-text&quot;&gt;Mimic&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;Mock&lt;/code&gt; when you need to mock external libraries you don’t have any control over.&lt;/p&gt;
&lt;p&gt;Until next time, happy mocking!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Database Performance Optimization and Scaling in Rails]]></title><description><![CDATA[Web applications usually rely heavily on databases, for the most part. And as applications grow, databases grow too. We keep scaling web servers and background workers to keep up with the heavy load. But eventually, the database needs to keep up with all the new connections from these processes.]]></description><link>https://pulkitgoyal.in/database-performance-optimization-scaling</link><guid isPermaLink="false">https://pulkitgoyal.in/database-performance-optimization-scaling</guid><pubDate>Thu, 16 Feb 2023 06:46:10 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1676530368/db-optimization_kaqu1a.png&quot; alt=&quot;Image taken from AppSignal&quot;&gt;&lt;/p&gt;
&lt;p&gt;Web applications usually rely heavily on databases, for the most part. And as applications grow, databases grow too. We keep scaling web servers and background workers to keep up with a heavy load. But eventually, the database needs to keep up with all the new connections from these processes.&lt;/p&gt;
&lt;p&gt;One way to tackle this is to grow a database with an app using vertical scaling. This means adding more CPU power and memory to the database server. But this is usually slow. You might have to copy all your data to the new server and then put the application down to change the database servers that it communicates with.&lt;/p&gt;
&lt;p&gt;This is also usually a one-way operation. You can’t keep adding/removing CPU power or memory from the database server based on your load.&lt;/p&gt;
&lt;p&gt;This post will cover some alternative methods to fine-tune and scale a database under heavy load and improve the performance of your Rails app. We will focus on:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Splitting schema and data between multiple databases&lt;/li&gt;
&lt;li&gt;Using read-only replica databases&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s get going!&lt;/p&gt;
&lt;h2&gt;Disclaimer: Scaling Isn’t Always Needed&lt;/h2&gt;
&lt;p&gt;As always with any post about performance optimization and scaling, I would like to put up a standard disclaimer: &lt;strong&gt;make sure you have an issue before trying to solve it&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, on one of our apps in production, we tackled scaling and optimization only when we started processing more than 3 million background jobs a day.&lt;/p&gt;
&lt;p&gt;This will, of course, be different for different apps. But usually, a good indicator of whether you need to optimize is if your database is always running at high CPU or memory usage.&lt;/p&gt;
&lt;h2&gt;A Separate Database for Your Rails Application&lt;/h2&gt;
&lt;p&gt;Sometimes, simply using a separate database server for a part of your app is a good solution. For example, your app might do two different things that don’t have a big overlap. Alternatively, maybe there’s one very database-heavy feature, but it is used only rarely or by a small section of users. Go the way of a separate database server if - and only if - there is a clear distinction between the parts of your app that will use different databases.&lt;/p&gt;
&lt;p&gt;An example of this being useful is audit logging in a high-frequency app (or other kinds of very high-volume data that isn’t necessarily accessed very frequently). Let’s see how we can set this up.&lt;/p&gt;
&lt;p&gt;First, set up the &lt;code class=&quot;language-text&quot;&gt;database.yml&lt;/code&gt; to configure the second database. Let’s call the second database &lt;code class=&quot;language-text&quot;&gt;log&lt;/code&gt;. We’ll add a &lt;code class=&quot;language-text&quot;&gt;log_default&lt;/code&gt; entry for the secondary database with a common configuration across all environments:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;log_default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;&amp;amp;log_default&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;host&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; localhost
  &lt;span class=&quot;token key atrule&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DB_PORT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; 5432 %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
  &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
  &lt;span class=&quot;token key atrule&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DB_USER&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &quot;postgres&quot; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;password&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DB_PASSWORD&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;|&lt;/span&gt; &quot;postgres&quot; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;migrations_paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; db/log_migrate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The important bit here is the &lt;code class=&quot;language-text&quot;&gt;migrations_paths&lt;/code&gt; option that tells Rails where to find migrations related to this database.&lt;/p&gt;
&lt;p&gt;Then, update &lt;code class=&quot;language-text&quot;&gt;database.yml&lt;/code&gt; to configure access to the log database for &lt;code class=&quot;language-text&quot;&gt;development&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;test&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;production&lt;/code&gt; environments:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;development&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*default&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DB_NAME&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*log_default&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;LOG_DB_NAME&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;

&lt;span class=&quot;token key atrule&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*default&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; my_app_test
  &lt;span class=&quot;token key atrule&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token important&quot;&gt;*log_default&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;database&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; my_app_log_test

&lt;span class=&quot;token key atrule&quot;&gt;production&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;migrations_paths&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; db/log_migrate
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_LOG_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you can see, we move the configuration for each environment one level deeper. The configuration for our primary database lives inside the &lt;code class=&quot;language-text&quot;&gt;primary&lt;/code&gt; key for each environment. The second database’s configuration (that we call &lt;code class=&quot;language-text&quot;&gt;log&lt;/code&gt;) lives inside the &lt;code class=&quot;language-text&quot;&gt;log&lt;/code&gt; key. &lt;code class=&quot;language-text&quot;&gt;primary&lt;/code&gt; is a special keyword that tells Rails to use this database as the default.&lt;/p&gt;
&lt;p&gt;The next step is to set up &lt;code class=&quot;language-text&quot;&gt;ActiveRecord&lt;/code&gt; to use this new database. We first create a base class that establishes a connection to this database (instead of a primary one) using &lt;code class=&quot;language-text&quot;&gt;establish_connection&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;LogRecord&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abstract_class &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  establish_connection &lt;span class=&quot;token symbol&quot;&gt;:log&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And then we inherit from &lt;code class=&quot;language-text&quot;&gt;LogRecord&lt;/code&gt; instead of &lt;code class=&quot;language-text&quot;&gt;ApplicationRecord&lt;/code&gt; for all our records that should access the &lt;code class=&quot;language-text&quot;&gt;log&lt;/code&gt; DB:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuditLog&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;LogRecord&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that you keep using the rails generators for generating models and migrations by appending the &lt;code class=&quot;language-text&quot;&gt;--database log&lt;/code&gt; option to target the second database. The migration task now automatically migrates both databases, but if you need to only migrate one, you can use &lt;code class=&quot;language-text&quot;&gt;db:migrate:primary&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;db:migrate:log&lt;/code&gt; tasks.&lt;/p&gt;
&lt;p&gt;This works great if you clearly distinguish between two parts of the app. But what if you don’t have a clear idea of the database that’s creating issues? There are still a couple of options left. Let’s check them out.&lt;/p&gt;
&lt;h2&gt;Using Read-Only Replicas for Rails&lt;/h2&gt;
&lt;p&gt;Our second scaling option is to access data from read-only replicas while still writing to the primary database. This can improve performance for users who only browse parts of the app without performing any writing operations. Depending on your app’s use case, this can be 80% of your users or 10% of them. So, evaluate the behavior of your users or your application use case before going down this route.&lt;/p&gt;
&lt;p&gt;For an app with a majority of read-only users (like Twitter, for example), you can gain huge improvements in performance. New read-only replicas can be added/removed at will without affecting the primary database, which opens up options for auto-scalability.&lt;/p&gt;
&lt;p&gt;Let’s see how to set this up.&lt;/p&gt;
&lt;h3&gt;Setting up a Read-Only Replica&lt;/h3&gt;
&lt;p&gt;As usual, we will start with modifications to the &lt;code class=&quot;language-text&quot;&gt;database.yml&lt;/code&gt; config to include the replica:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;production&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary_replica&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_REPLICA_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Again, the &lt;code class=&quot;language-text&quot;&gt;primary&lt;/code&gt; key is a special key indicating that this database is the default. We can use any other key for the replica database configuration. Let’s choose &lt;code class=&quot;language-text&quot;&gt;primary_replica&lt;/code&gt; for sanity.&lt;/p&gt;
&lt;p&gt;Then update the &lt;code class=&quot;language-text&quot;&gt;ApplicationRecord&lt;/code&gt; to configure a connection to multiple databases:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ApplicationRecord&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;abstract_class &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;

  connects_to database&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; writing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:primary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; reading&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:primary_replica&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;production&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note that we add configuration for a &lt;code class=&quot;language-text&quot;&gt;production&lt;/code&gt; environment only in the above example. If you want to, you can set it up for all environments, after modifying your development setup to support replicas.&lt;/p&gt;
&lt;p&gt;Finally, to use the read-only replica, you need to tell Rails when to use the primary database and when to use the replica. Rails provides a basic implementation for automatic role-switching based on the HTTP verb of the request out of the box. To enable it, add the following to your &lt;code class=&quot;language-text&quot;&gt;production.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Use Read-Only Databases on GET requests&lt;/span&gt;
config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active_record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;database_selector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; delay&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;seconds &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active_record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;database_resolver &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Middleware&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DatabaseSelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Resolver&lt;/span&gt;
config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active_record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;database_resolver_context &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Middleware&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DatabaseSelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Resolver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Session&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tells Rails to use the replica for all &lt;code class=&quot;language-text&quot;&gt;GET&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;HEAD&lt;/code&gt; requests and the primary one otherwise. Notice the option that sets the delay to two seconds? That tells Rails to keep using the primary database for &lt;code class=&quot;language-text&quot;&gt;GET&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;HEAD&lt;/code&gt; requests if it is within two seconds of a write request in the same session.&lt;/p&gt;
&lt;h3&gt;Gotchas&lt;/h3&gt;
&lt;p&gt;Does all of this sound too simple? Well, we aren’t done yet. Depending on how your application is structured, you need to keep a few points in mind.&lt;/p&gt;
&lt;p&gt;Firstly, ensure you do not write anything in a read-only action like &lt;code class=&quot;language-text&quot;&gt;index&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;show&lt;/code&gt;. If there are legitimate reasons for writing during those operations, you can manually switch the connection:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;connected_to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;role&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:writing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Your code here&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A good example where this can be useful is if you are managing sessions in a database. If you do that, make sure you use the &lt;code class=&quot;language-text&quot;&gt;writing&lt;/code&gt; role. For example, you can override the &lt;code class=&quot;language-text&quot;&gt;save_record&lt;/code&gt; method in your session with &lt;code class=&quot;language-text&quot;&gt;authlogic&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;UserSession&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Authlogic&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# Your session configuration&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;save_record&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;alternate_record &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;connected_to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;role&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:writing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another use case for automatic role-switching is when an app exposes a GraphQL API. All operations on a GraphQL API are &lt;code class=&quot;language-text&quot;&gt;POST&lt;/code&gt;, but conventionally, all &lt;code class=&quot;language-text&quot;&gt;queries&lt;/code&gt; are read-only, and &lt;code class=&quot;language-text&quot;&gt;mutations&lt;/code&gt; are read-write.  In this case, to allow Rails to select the correct database, we can use a custom tracer in the schema.&lt;/p&gt;
&lt;p&gt;First, create a tracer that switches roles based on the GraphQL document:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Tracers&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DatabaseRoleTracer&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;EVENT_NAME&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;execute_multiplex&quot;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;# Execute on read only database if the operation has only queries.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;trace&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;production&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; event &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EVENT_NAME&lt;/span&gt;

      multiplex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:multiplex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;connected_to&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;role&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; role&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;multiplex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;yield&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;role&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;multiplex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; multiplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;all&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:query?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;reading_role
      &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;writing_role
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And then use the &lt;code class=&quot;language-text&quot;&gt;tracer&lt;/code&gt; in your GraphQL Schema:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyAppSchema&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;GraphQL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Schema&lt;/span&gt;
  tracer &lt;span class=&quot;token constant&quot;&gt;Tracers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DatabaseRoleTracer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# Your code here&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s get to the final alternative What can you do if your application still has a huge load on your primary database? The answer: database sharding.&lt;/p&gt;
&lt;h2&gt;Database Sharding in Your Rails Application&lt;/h2&gt;
&lt;p&gt;This is the most complex of all the methods for scaling databases discussed in this post. So reach for it only if you need it. It will add considerable complexity to your application and needs to be done right to provide any real benefit.&lt;/p&gt;
&lt;p&gt;There are two strategies to shard your database:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Distribute different tables on different nodes (vertical sharding).&lt;/li&gt;
&lt;li&gt;Have the same schema across all nodes, but distribute data depending on certain parameters (horizontal sharding).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Vertical sharding is similar to our “multiple databases” strategy in terms of setup and pros and cons, so we will not discuss it again.&lt;/p&gt;
&lt;p&gt;Let’s discuss horizontal sharding and where it could be helpful.&lt;/p&gt;
&lt;p&gt;One example is when you have a SaaS platform where a lot of data is associated with each user, but there is no overlap between the data of two users. In this case, splitting the data across nodes based on the user’s id is the most logical way to go. Every signed-in user will have to access only a single database, so we won’t have to reach out to multiple databases at the same time.&lt;/p&gt;
&lt;h3&gt;Setting up Horizontal Sharding&lt;/h3&gt;
&lt;p&gt;Let’s start with the configuration inside &lt;code class=&quot;language-text&quot;&gt;database.yml&lt;/code&gt; again:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;production&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary_replica&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_REPLICA_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;primary_shard_one&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_SHARD_ONE_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;
	&lt;span class=&quot;token key atrule&quot;&gt;primary_shard_one_replica&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;adapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; postgresql
    &lt;span class=&quot;token key atrule&quot;&gt;encoding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; unicode
    &lt;span class=&quot;token key atrule&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &amp;lt;%= ENV&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;DATABASE_SHARD_ONE_REPLICA_URL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; %&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then modify the &lt;code class=&quot;language-text&quot;&gt;ApplicationRecord&lt;/code&gt; to connect to different shards:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yaml&quot;&gt;&lt;pre class=&quot;language-yaml&quot;&gt;&lt;code class=&quot;language-yaml&quot;&gt;class ApplicationRecord &amp;lt; ActiveRecord&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;Base
  self.abstract_class = true

  connects_to shards&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;writing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;primary&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;reading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;primary_replica &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;shard_one&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;writing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;primary_shard_one&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token key atrule&quot;&gt;reading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;primary_shard_one_replica &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can use the &lt;code class=&quot;language-text&quot;&gt;shard&lt;/code&gt; option with &lt;a href=&quot;https://edgeapi.rubyonrails.org/classes/ActiveRecord/ConnectionHandling.html#method-i-connected_to&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ActiveRecord::Base.connected_to&lt;/code&gt;&lt;/a&gt; to switch shards. Like the automatic database role selector, Rails also provides an automatic shard switcher that can be activated inside &lt;code class=&quot;language-text&quot;&gt;production.rb&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;application&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;configure &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active_record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shard_selector &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; lock&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;active_record&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shard_resolver &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;request&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Tenant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;find_by&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;host&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shard &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;shard_resolver&lt;/code&gt; lambda is the most interesting part. The above implementation relies on the assumption that our application is accessed from different domains/subdomains and distinguishes between the shards. Modify it to fit your application needs (you might need to access cookies to identify a user before switching the shard).&lt;/p&gt;
&lt;p&gt;As with vertical scaling, this strategy is usually a one-way street. Once you shard a database, it is very hard to “un-shard” it (since several databases could have the same ids for different objects). But this lays down the foundation to really scale your app to millions or billions of users when fitting everything on the same server is not an option.&lt;/p&gt;
&lt;p&gt;If you want to read more about database sharding, see this &lt;a href=&quot;https://www.linode.com/docs/guides/sharded-database/&quot;&gt;write-up by Linode&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Wrap Up&lt;/h2&gt;
&lt;p&gt;In this post, we discussed three major strategies to scale your database servers horizontally:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Splitting schema between multiple databases&lt;/li&gt;
&lt;li&gt;Using read-only replica databases&lt;/li&gt;
&lt;li&gt;Splitting data between multiple databases&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All strategies have their pros and cons depending on your application use case and scale.
Rails has really upped its database game in its last few releases. This post shows how easy it is to set up a Rails app to use multiple databases.
As always, if your application allows it, I suggest starting small with optimizations. The easiest optimization to start with is a read-only replica, then only move on when you need more scale.&lt;/p&gt;
&lt;p&gt;Happy scaling!&lt;/p&gt;
&lt;p&gt;-﻿-----------------&lt;/p&gt;
&lt;p&gt;This article was originally posted on &lt;a href=&quot;https://blog.appsignal.com/2022/12/07/database-performance-optimization-and-scaling-in-rails.html&quot;&gt;AppSignal Blog&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[State Machines in Ruby: An Introduction]]></title><description><![CDATA[A state machine can hold all possible states of something and the allowed transitions between these states. For example, the state machine for a door would have only two states (open and closed) and only two transitions (opening and closing).]]></description><link>https://pulkitgoyal.in/state-machines-in-ruby</link><guid isPermaLink="false">https://pulkitgoyal.in/state-machines-in-ruby</guid><pubDate>Mon, 11 Jul 2022 05:28:33 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_787/v1657517591/pattern-matching_qxm4pw_v5bcds.jpg&quot; alt=&quot;An Introduction to Pattern Matching in Ruby&quot;&gt;&lt;/p&gt;
&lt;p&gt;A state machine can hold all possible states of &lt;em&gt;something&lt;/em&gt; and the allowed transitions between these states.
For example, the state machine for a door would have only two states (&lt;code class=&quot;language-text&quot;&gt;open&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;closed&lt;/code&gt;) and only two transitions (&lt;code class=&quot;language-text&quot;&gt;opening&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;closing&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;On the other hand, complex state machines can have several different states with hundreds of transitions between them.
In fact, if you look around, you will notice finite state machines surrounding you  - when you buy from a website, get a pack of crisps from the vending machine, or even just withdraw money from an ATM.&lt;/p&gt;
&lt;p&gt;In this post, we’ll look at how to set up a state machine in Ruby and use the state machines gem.&lt;/p&gt;
&lt;h2&gt;State Machines in Development&lt;/h2&gt;
&lt;p&gt;When do we need a state machine in development? The simple answer is whenever you want to model multiple rules for state transitions or perform side-effects on some transitions.
The key here is to identify parts of your application that would benefit from a state machine.
A good example that always works for me is an &lt;code class=&quot;language-text&quot;&gt;Order&lt;/code&gt; in the context of an e-commerce application.&lt;/p&gt;
&lt;p&gt;For a simple application selling products online, an Order can be in one of several states:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;created&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;processing&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ready&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;shipped&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;delivered&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;void&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see the allowed transitions in the following diagram.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1657517447/order-state-machine_lkphag.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;Visualizing the order in the form of a state machine immediately allows us to clearly understand of the full flow, from ordering the product to delivery.
And for us developers, it will enable clear, set steps on what can and cannot be done at particular points in that flow.&lt;/p&gt;
&lt;p&gt;That being said, it is easy to jump down a rabbit hole by picking this up for a very wide problem and then end up with hundreds of states that are difficult to reason about and follow through.
So always have a top-level idea and a state chart for your proposed state machine before implementing it.&lt;/p&gt;
&lt;h2&gt;Our First State Machine in Ruby&lt;/h2&gt;
&lt;p&gt;Let’s try to implement our &lt;code class=&quot;language-text&quot;&gt;OrderStateMachine&lt;/code&gt; with Ruby.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OrderStateMachine&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;initialize&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;order&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; order
    &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:created&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;blank&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;mark_as_paid&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Invalid state &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;created&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:processing&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;packed&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Invalid state &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;processing&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:ready&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;shipped&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Invalid state &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ready&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:shipped&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s a simple enough implementation.
For each possible transition in the state machine, we define a new method that does some sanity checks and performs the transition.&lt;/p&gt;
&lt;p&gt;The great thing about the above implementation is that everything is explicit: any new developer can very quickly understand the full extent of the state machine.&lt;/p&gt;
&lt;p&gt;Let’s see how we can add some side-effects to the transitions.
We’ll automatically ship orders that are packed and deliverable:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OrderStateMachine&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;packed&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Invalid state &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;processing&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;

    &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:ready&lt;/span&gt;
    ship_order &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deliverable&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;ship_order&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;DeliveryService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_consigment&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;@order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    shipped&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While a naïve implementation works great, it is overly verbose, especially when we have a lot of transitions and conditions.&lt;/p&gt;
&lt;p&gt;A quick check on &lt;a href=&quot;https://www.ruby-toolbox.com/categories/state_machines&quot;&gt;Ruby Toolbox&lt;/a&gt; brings up several gems for state machines.
&lt;a href=&quot;https://github.com/state-machines/state_machines&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;state_machines&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;https://github.com/aasm/aasm&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;aasm&lt;/code&gt;&lt;/a&gt; are the most popular ones, and both come with an ActiveRecord adapter if you want to use them with Rails.
Both are thoroughly tested and production-ready, so do check them out if you need to implement a state machine.&lt;/p&gt;
&lt;h2&gt;Using the State Machines Gem in Ruby&lt;/h2&gt;
&lt;p&gt;For this post, I will describe how we can model the state machine for our &lt;code class=&quot;language-text&quot;&gt;Order&lt;/code&gt; using the &lt;code class=&quot;language-text&quot;&gt;state_machines&lt;/code&gt; gem.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Order&lt;/span&gt;
  state_machine &lt;span class=&quot;token symbol&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; initial&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:created&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    event &lt;span class=&quot;token symbol&quot;&gt;:confirm_payment&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      transition created&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:processing&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    event &lt;span class=&quot;token symbol&quot;&gt;:pack&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      transition processing&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:ready&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    event &lt;span class=&quot;token symbol&quot;&gt;:cancel&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      transition &lt;span class=&quot;token string&quot;&gt;%i[created processing ready]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:void&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    event &lt;span class=&quot;token symbol&quot;&gt;:return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      transition delivered&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:void&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    event &lt;span class=&quot;token symbol&quot;&gt;:ship&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      transition ready&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:shipped&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    event &lt;span class=&quot;token symbol&quot;&gt;:fail_delivery&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      transition shipped&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:processing&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above class defines our simple state machine and all of its possible transitions.
On top of this, it also automatically exposes a lot of utility methods on an order:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state           &lt;span class=&quot;token comment&quot;&gt;# =&gt; &quot;created&quot;&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state_name      &lt;span class=&quot;token comment&quot;&gt;# =&gt; :created&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;created&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;        &lt;span class=&quot;token comment&quot;&gt;# =&gt; true&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;can_pack&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;# =&gt; false (since payment has not been confirmed yet)&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;confirm_payment &lt;span class=&quot;token comment&quot;&gt;# =&gt; true (and transitions to `processing`)&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;can_pack&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;       &lt;span class=&quot;token comment&quot;&gt;# =&gt; true&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Execute Side-Effects with the State Machines Gem in Ruby&lt;/h2&gt;
&lt;p&gt;As is usual for any real-world system, many transitions in a state machine will come with some side effects.
The &lt;code class=&quot;language-text&quot;&gt;state_machines&lt;/code&gt; gem makes it easy to define and execute them.
Let’s add two side-effects:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;On all transitions to ready, create a delivery consignment if the order is &lt;code class=&quot;language-text&quot;&gt;deliverable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On all &lt;code class=&quot;language-text&quot;&gt;fail_delivery&lt;/code&gt; events, send an email to the user notifying them of the event.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Order&lt;/span&gt;
  attr_accessor &lt;span class=&quot;token symbol&quot;&gt;:deliverable&lt;/span&gt;

  state_machine &lt;span class=&quot;token symbol&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; initial&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:created&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;

    after_transition to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:ready&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:create_delivery_consignment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:deliverable&lt;/span&gt;
    after_transition on&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:fail_delivery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:notify_delivery_failure&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;create_delivery_consignment&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;DeliveryService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_consigment&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    ship
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;notify_delivery_failure&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;UserMailer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;delivery_failure_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deliver_later
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can perform transitions as usual in the order:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deliverable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pack            &lt;span class=&quot;token comment&quot;&gt;# =&gt; true&lt;/span&gt;
order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state           &lt;span class=&quot;token comment&quot;&gt;# =&gt; &quot;shipped&quot; (through side-effect)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I would suggest checking out the &lt;a href=&quot;https://github.com/state-machines/state_machines&quot;&gt;Github page for the &lt;code class=&quot;language-text&quot;&gt;state_machines&lt;/code&gt; gem&lt;/a&gt; to learn about all the possible options that the gem offers.&lt;/p&gt;
&lt;h2&gt;Use the State Machines Gem with ActiveRecord in Ruby on Rails&lt;/h2&gt;
&lt;p&gt;As discussed before, both &lt;code class=&quot;language-text&quot;&gt;state_machines&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;aasm&lt;/code&gt; support ActiveRecord.
When you use the &lt;code class=&quot;language-text&quot;&gt;state_machines&lt;/code&gt; gem with ActiveRecord, not a lot of things change with the implementation. You can continue using most of what we’ve already discussed in the previous sections of this post.&lt;/p&gt;
&lt;p&gt;Here are some additional features that you get:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Side-effects happen inside a transaction.
This means that if you do some database operations inside transition hooks and the transaction fails, the state change won’t be committed.
&lt;a href=&quot;https://www.rubydoc.info/github/state-machines/state_machines-activerecord/StateMachines/Integrations/ActiveRecord#label-Transactions&quot;&gt;See &lt;code class=&quot;language-text&quot;&gt;use_transactions&lt;/code&gt;&lt;/a&gt;  if you want to disable this behavior.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Like all other ActiveRecord callbacks, if you want to update the attributes of the current model from a transition, you must do this inside a &lt;code class=&quot;language-text&quot;&gt;before_transition&lt;/code&gt; callback.
To update attributes inside &lt;code class=&quot;language-text&quot;&gt;after_transition&lt;/code&gt;, you need to save the model again.
Check out the following example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Order&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
  state_machine initial&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:created&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;

    before_transition any &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:processing&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;order&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# You can just update the attribute here and it will be saved.&lt;/span&gt;
      order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;processing_start_at &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;now
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    after_transition any &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:shipped&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;order&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Call update! to update the order.&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# Just setting the attribute like above would not work here.&lt;/span&gt;
      order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;update&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shipped_at&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;zone&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;now&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;The gem automatically provides scopes to filter models by their state.
For example, you can do &lt;code class=&quot;language-text&quot;&gt;Order.with_state(:processing)&lt;/code&gt; to find all the processing orders or &lt;code class=&quot;language-text&quot;&gt;Order.without_state(:processing)&lt;/code&gt; to find all orders that are not under processing.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If a state change is attempted without a matching transition (for example, from &lt;code class=&quot;language-text&quot;&gt;processing&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;delivered&lt;/code&gt;), the record will fail to save, and an error will be added to the validation errors.
To internationalize the generated error messages, just add some keys to provide translations for states and events inside the config files (for example, &lt;code class=&quot;language-text&quot;&gt;en.yml&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;yml&quot;&gt;&lt;pre class=&quot;language-yml&quot;&gt;&lt;code class=&quot;language-yml&quot;&gt;&lt;span class=&quot;token key atrule&quot;&gt;en&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;token key atrule&quot;&gt;activerecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token key atrule&quot;&gt;state_machines&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token key atrule&quot;&gt;order&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;states&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;created&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Created
          &lt;span class=&quot;token key atrule&quot;&gt;processing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Under Processing
          &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
        &lt;span class=&quot;token key atrule&quot;&gt;events&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;token key atrule&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; Return Order
          &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Wrap Up: Build State Machines in Ruby&lt;/h2&gt;
&lt;p&gt;In this post, we explored why we’d use a state machine in development, before building a simple state machine. Finally, we looked at using the state machines gem in Ruby and Ruby on Rails.&lt;/p&gt;
&lt;p&gt;Now that you have a basic understanding of a state machine, I am sure you will recognize several scenarios around you that already use a state machine or will benefit greatly from one.&lt;/p&gt;
&lt;p&gt;Until next time, I wish you luck building state machines!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This article was originally posted on &lt;a href=&quot;https://blog.appsignal.com/2022/06/22/state-machines-in-ruby-an-introduction.html&quot;&gt;AppSignal Blog&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using Profiling in Elixir to Improve Performance]]></title><description><![CDATA[Elixir is all about performance. Say you have an app up and running with Elixir, but some parts aren't working as fast as you would like them to.]]></description><link>https://pulkitgoyal.inprofiling-in-elixir</link><guid isPermaLink="false">https://pulkitgoyal.inprofiling-in-elixir</guid><pubDate>Wed, 11 May 2022 08:58:28 GMT</pubDate><content:encoded>&lt;p&gt;Elixir is all about performance. Say you have an app up and running with Elixir, but some parts aren’t working as fast as you would like them to.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_750/v1652258300/profiling.png&quot; alt=&quot;Profiling in Elixir&quot; title=&quot;Profiling in Elixir&quot;&gt;&lt;/p&gt;
&lt;p&gt;That is where profiling comes in. Profiling tools usually walk you through the frequency and duration of function calls and where they spend their time.
Erlang has impressive profile tooling available at its disposal.&lt;/p&gt;
&lt;p&gt;In this post, we will look into three profiling tools in Elixir: &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt;, and &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Do I Need Profiling for My Elixir App?&lt;/h2&gt;
&lt;p&gt;Firstly, I want to clarify that you may not need profiling at all. As Donald Knuth wrote: &lt;em&gt;‘premature optimization is the root of all evil.’&lt;/em&gt; Some operations just cannot be optimized.&lt;/p&gt;
&lt;p&gt;For example, say you want to fetch something from your database. You issue a query and get a reply. This incurs a network round trip with some data. If you need all the data, the network round trip time cannot be optimized without moving your database closer to the app.&lt;/p&gt;
&lt;p&gt;With that out of the way, let’s jump into profiling options.&lt;/p&gt;
&lt;h2&gt;Profiling with &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt; in Elixir&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt; counts the number of times each function is invoked. It doesn’t profile the time spent in those functions, so it comes with the least amount of overhead.&lt;/p&gt;
&lt;p&gt;Use it when you already have an estimate of your functions’ runtimes. You’ll see the frequency with which each function is invoked.&lt;/p&gt;
&lt;p&gt;Let’s see how we can profile a Fibonacci number generator with &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://gist.github.com/pulkit110/c8223b7ebf4dc6cb918f440c45e201cd&quot;&gt;follow along with the code&lt;/a&gt;.
It uses the &lt;a href=&quot;https://rosettacode.org/wiki/Fibonacci_sequence#Elixir&quot;&gt;Rosetta Code algorithm for Fibonacci sequence generation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Jump into an IEx session and run &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;iex&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:cprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;19244&lt;/span&gt;
iex&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;34&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;55&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
iex&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;17&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:cprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;analyse&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;79&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:fibonacci&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;54&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:fibonacci&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; :&lt;span class=&quot;token string&quot;&gt;&quot;-fun.fibonacci/1-&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:module_info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:__info__&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
iex&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;18&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:cprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stop&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;19266&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First start &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt;, run the code that you want to profile, and then call &lt;code class=&quot;language-text&quot;&gt;:cprof.analyse/1&lt;/code&gt; to fetch the statistics for the given module. Several other options are available inside the &lt;a href=&quot;https://www.erlang.org/doc/man/cprof.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;:cprof&lt;/code&gt; module&lt;/a&gt;, like pausing profiling with &lt;code class=&quot;language-text&quot;&gt;:cprof.pause/0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;We can also use Mix’s wrapper task &lt;a href=&quot;https://hexdocs.pm/mix/1.12/Mix.Tasks.Profile.Cprof.html&quot;&gt;profile.cprof&lt;/a&gt; directly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;➜ mix profile.cprof -e &amp;quot;FibonacciRosettaCode.list(10)&amp;quot;
                                                                     CNT
Total                                                                113
FibonacciRosettaCode                                                  77  &amp;lt;--
  FibonacciRosettaCode.fibonacci/3                                    54
  FibonacciRosettaCode.fibonacci/1                                    11
  FibonacciRosettaCode.&amp;quot;-fun.fibonacci/1-&amp;quot;/1                          11
  FibonacciRosettaCode.list/1                                          1
Enum                                                                  24  &amp;lt;--
  Enum.reduce_range/5                                                 12
  anonymous fn/3 in Enum.map/2                                        11
  Enum.map/2                                                           1
  ...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, we can see that the function &lt;code class=&quot;language-text&quot;&gt;fibonacci/3&lt;/code&gt; is called the most times. So if we can somehow decrease the number of calls to that function or optimize the code inside it, we could improve performance.&lt;/p&gt;
&lt;h2&gt;&lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt; Profiling in Elixir&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt; measures &lt;em&gt;counts&lt;/em&gt; while &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt; measures the  &lt;em&gt;execution time&lt;/em&gt; (in addition to counts) spent inside each function. It has slightly more overhead than &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt;. Use &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt; when you want to find the most time-consuming functions.&lt;/p&gt;
&lt;p&gt;The usage is very similar to &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt;. You just need to &lt;code class=&quot;language-text&quot;&gt;start&lt;/code&gt; the profiler, run the code you want to profile and then call &lt;code class=&quot;language-text&quot;&gt;analyze&lt;/code&gt; to fetch the results.&lt;/p&gt;
&lt;p&gt;Let’s analyze the results from the mix task &lt;a href=&quot;https://hexdocs.pm/mix/1.12/Mix.Tasks.Profile.Eprof.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;profile.eprof&lt;/code&gt;&lt;/a&gt; on our sample Fibonacci generator.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;➜ mix profile.eprof -e &amp;quot;FibonacciRosettaCode.list(10)&amp;quot;
#                                               CALLS     % TIME µS/CALL
Total                                             106 100.0   45    0.42
anonymous fn/0 in :elixir_compiler_1.__FILE__/1     1  0.00    0    0.00
:lists.reverse/1                                    1  2.22    1    1.00
:lists.reverse/2                                    1  2.22    1    1.00
FibonacciRosettaCode.fibonacci/1                   11  4.44    2    0.18
Enum.map/2                                          1  4.44    2    2.00
Range.new/2                                         1  4.44    2    2.00
FibonacciRosettaCode.&amp;quot;-fun.fibonacci/1-&amp;quot;/1         11  8.89    4    0.36
FibonacciRosettaCode.list/1                         1  8.89    4    4.00
:erlang.apply/2                                     1  8.89    4    4.00
anonymous fn/3 in Enum.map/2                       11 13.33    6    0.55
Enum.reduce_range/5                                12 13.33    6    0.50
FibonacciRosettaCode.fibonacci/3                   54 28.89   13    0.24&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here we can see that &lt;code class=&quot;language-text&quot;&gt;fibonacci/3&lt;/code&gt; is again the most time-consuming part of our program, consuming 28.89% of the total execution time and 0.24µS per call.&lt;/p&gt;
&lt;p&gt;In addition, &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt; also allows us to profile function calls across different processes. The usage is very simple. Let’s see an example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:eprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start_profiling&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Do some work&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; Enum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;each&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
  spawn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token atom symbol&quot;&gt;:eprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;stop_profiling&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token atom symbol&quot;&gt;:eprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;analyze&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You need to call &lt;code class=&quot;language-text&quot;&gt;start_profiling/1&lt;/code&gt; with a list of processes to profile. By default, this also tracks any other processes started from a profiled process.&lt;/p&gt;
&lt;p&gt;When you are done, call &lt;code class=&quot;language-text&quot;&gt;stop_profiling&lt;/code&gt; and run &lt;code class=&quot;language-text&quot;&gt;analyze&lt;/code&gt; to get the results. They should look something like this, with an entry for each process and the percentage of time it was busy:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;****** Process &amp;lt;0.150.0&amp;gt;    -- 37.26 % of profiled time ***
FUNCTION                                                             CALLS        %   TIME  [uS / CALLS]
--------                                                             -----  -------   ----  [----------]
io:request/2                                                             3     0.00      0  [      0.00]
...

****** Process &amp;lt;0.277.0&amp;gt;    -- 0.05 % of profiled time ***
FUNCTION                                             CALLS        %  TIME  [uS / CALLS]
--------                                             -----  -------  ----  [----------]
&amp;#39;Elixir.FibonacciRosettaCode&amp;#39;:fibonacci/3                2     0.00     0  [      0.00]
&amp;#39;Elixir.FibonacciRosettaCode&amp;#39;:fibonacci/1                3     3.03     1  [      0.33]
&amp;#39;Elixir.FibonacciRosettaCode&amp;#39;:&amp;#39;-fun.fibonacci/1-&amp;#39;/1      3     3.03     1  [      0.33]
...&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The great thing about this is that you can run it in production systems by accessing the remote console. Just call &lt;code class=&quot;language-text&quot;&gt;start_profiling/1&lt;/code&gt;, wait some time to process the requests or manually trigger some requests you want to profile. Then call &lt;code class=&quot;language-text&quot;&gt;stop_profiling&lt;/code&gt; followed by &lt;code class=&quot;language-text&quot;&gt;analyze&lt;/code&gt; to get the results.&lt;/p&gt;
&lt;h2&gt;Using &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; in Elixir&lt;/h2&gt;
&lt;p&gt;The final inbuilt tool you can use to profile your applications is &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt;. It is a comprehensive profiling tool that generates a trace file containing timestamped entries for function calls, process-related events, and garbage collection data.&lt;/p&gt;
&lt;p&gt;You can then feed this trace file into other tools to visualize the results thoroughly or use &lt;code class=&quot;language-text&quot;&gt;:fprof.analyse&lt;/code&gt; like above to fetch function counts and execution times.&lt;/p&gt;
&lt;p&gt;Running &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; through IEx is quite advanced compared to running &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt;, but &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; allows tracing multiple processes.&lt;/p&gt;
&lt;p&gt;Here is how you can generate a trace file for all processes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:fprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token atom symbol&quot;&gt;:fprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;procs:&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:all&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Do some work&lt;/span&gt;
&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; Enum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;each&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
  spawn&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; FibonacciRosettaCode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;list&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token atom symbol&quot;&gt;:fprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trace&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token atom symbol&quot;&gt;:fprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token atom symbol&quot;&gt;:fprof&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;analyse&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;totals:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;dest:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;prof.analysis&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This generates a comprehensive trace of everything that went on during the run with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;CNT&lt;/code&gt; - the number of times a function is called&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ACC&lt;/code&gt; - the accumulated time spent in the function, including other function calls&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;OWN&lt;/code&gt; - the time the function spent to be executed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&quot;https://gist.github.com/pulkit110/10ad017e52ad25c6b0ad36199544fd8f&quot;&gt;Here’s the full file (50 MB)&lt;/a&gt; if you are interested.&lt;/p&gt;
&lt;p&gt;Like &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; is a great tool to profile applications in production directly. Note that this will significantly slow down the application, so be prepared for degraded performance during profiling and a huge trace file.&lt;/p&gt;
&lt;p&gt;So you have the data now. If you are feeling adventurous, you can start digging through the file and looking for patterns.&lt;/p&gt;
&lt;p&gt;Or you can use some tools to help visualize your data. A popular one is &lt;a href=&quot;https://github.com/isacssouza/erlgrind&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;erlgrind&lt;/code&gt;&lt;/a&gt;. It converts the &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; file to &lt;code class=&quot;language-text&quot;&gt;cgrind&lt;/code&gt; format that you can open inside &lt;a href=&quot;https://kcachegrind.github.io/html/Home.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;KCachegrind&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To convert the file, download &lt;code class=&quot;language-text&quot;&gt;erlgrind&lt;/code&gt; and then run &lt;code class=&quot;language-text&quot;&gt;src/erlgrind profile.fprof&lt;/code&gt;.
This will generate a &lt;code class=&quot;language-text&quot;&gt;prof.cgrind&lt;/code&gt; file that you can open to see graphs like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1652258509/cgrind_gcn0a2.jpg&quot; alt=&quot;qcachegrind graph&quot;&gt;&lt;/p&gt;
&lt;h2&gt;Profile and Collect Metrics from Your Elixir App in Production&lt;/h2&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; can assist you with profiling your application in production. But there are a couple of additional tools worth mentioning - Phoenix Live Dashboard and Recon.&lt;/p&gt;
&lt;h3&gt;Phoenix Live Dashboard&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/phoenixframework/phoenix_live_dashboard&quot;&gt;Phoenix’s live dashboard&lt;/a&gt; can provide a great, quick overview of metrics. While not exactly a profiler, it shows OS data and metrics from telemetry events and processes, among other things.&lt;/p&gt;
&lt;p&gt;Here is an example of the dashboard in action:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1652258510/phoenix-live-dashboard_o78t8n.jpg&quot; alt=&quot;Phoenix Live Dashboard Screenshot&quot;&gt;&lt;/p&gt;
&lt;h3&gt;Recon&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://ferd.github.io/recon/&quot;&gt;Recon&lt;/a&gt; is another great library that can be dropped into any project and help diagnose problems in production. It works with very little overhead and provides production-safe tracing helpers.&lt;/p&gt;
&lt;p&gt;You can simply install it by adding the &lt;code class=&quot;language-text&quot;&gt;recon&lt;/code&gt; dependency to &lt;code class=&quot;language-text&quot;&gt;mix.exs&lt;/code&gt;. You can then start tracing calls to any function by using &lt;a href=&quot;https://ferd.github.io/recon/recon_trace.html#calls-3&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;:recon_trace.calls/3&lt;/code&gt;&lt;/a&gt; like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;:recon_trace.calls({FibonacciRosettaCode, :fibonacci, :return_trace}, 10)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will trace all calls made to &lt;code class=&quot;language-text&quot;&gt;FibonacciRosettaCode.fibonacci&lt;/code&gt; for up to 10 lines, with one line for function call arguments and one for the return value with timestamps.&lt;/p&gt;
&lt;p&gt;There is a lot more to &lt;code class=&quot;language-text&quot;&gt;recon&lt;/code&gt;, though, so I suggest you check out the &lt;a href=&quot;https://ferd.github.io/recon/index.html&quot;&gt;Recon homepage&lt;/a&gt; for advanced usage.&lt;/p&gt;
&lt;h3&gt;AppSignal&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://appsignal.com/&quot;&gt;AppSignal&lt;/a&gt; is another great tool to collect performance data (among other things). [Adding AppSignal to an existing application (&lt;a href=&quot;https://docs.appsignal.com/elixir/installation/#installing-the-package&quot;&gt;https://docs.appsignal.com/elixir/installation/#installing-the-package&lt;/a&gt;) takes a few seconds. Just install the &lt;code class=&quot;language-text&quot;&gt;appsignal&lt;/code&gt; dependency and run the &lt;code class=&quot;language-text&quot;&gt;appsignal.install&lt;/code&gt; mix task with an API key. It has a good set of default metric collection including the throughput and response times for the application.
You could even set up &lt;a href=&quot;https://docs.appsignal.com/elixir/instrumentation/minutely-probes.html&quot;&gt;minutely probes&lt;/a&gt; to track custom metrics.
Here’s an example of the AppSignal dashboard collecting data from a sample application:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1652258508/appsignal_ys4mvn.jpg&quot; alt=&quot;AppSignal Screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;If you are looking to collect data about specific blocks of code that you suspect are slow, AppSignal’s instrumentation feature can help collect data about it. Just wrap the suspected code inside &lt;code class=&quot;language-text&quot;&gt;Appsignal.instrument/2&lt;/code&gt; like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;PageController &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;use&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:controller&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;conn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    custom_function&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    render&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;conn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;index.html&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; custom_function &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    Appsignal&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instrument&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;custom_function&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;token atom symbol&quot;&gt;:timer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sleep&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will show up on the AppSignal event graph tagged as &lt;code class=&quot;language-text&quot;&gt;custom_function&lt;/code&gt;. You can then explore this event across multiple calls and make an informed decision about the need for optimization.&lt;/p&gt;
&lt;p&gt;Check out the full list of features on &lt;a href=&quot;https://docs.appsignal.com/elixir/&quot;&gt;the AppSignal docs&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Wrap-up: Measure Your Elixir App’s Performance with Profiling&lt;/h2&gt;
&lt;p&gt;In this post, we saw how inbuilt tools like &lt;code class=&quot;language-text&quot;&gt;cprof&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;eprof&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;fprof&lt;/code&gt; can help gather performance insights for your code, even during production.&lt;/p&gt;
&lt;p&gt;We also took a quick look at a couple of other tools to monitor and trace your applications: Phoenix Live Dashboard and Recon.&lt;/p&gt;
&lt;p&gt;Until next time, happy profiling!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This article was originally posted on &lt;a href=&quot;https://blog.appsignal.com/2022/04/26/using-profiling-in-elixir-to-improve-performance.html&quot;&gt;AppSignal Blog&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[An Introduction to Pattern Matching in Ruby]]></title><description><![CDATA[This post looks at the new pattern matching support for Ruby 2.7+ and how we can use it to make our code more readable.]]></description><link>https://pulkitgoyal.in/introduction-to-pattern-matching-in-ruby</link><guid isPermaLink="false">https://pulkitgoyal.in/introduction-to-pattern-matching-in-ruby</guid><pubDate>Wed, 16 Feb 2022 05:57:32 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1627889026/pattern-matching_qxm4pw.jpg&quot; alt=&quot;An Introduction to Pattern Matching in Ruby&quot;&gt;&lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;
  Image from &lt;a href=&quot;https://blog.appsignal.com/2021/07/28/introduction-to-pattern-matching-in-ruby.html&quot; target=&quot;_blank&quot;&gt;AppSignal Blog&lt;/a&gt;
&lt;/div&gt;
&lt;p&gt;Let’s start with a brief discussion about pattern matching in Ruby, what it does, and how it can help improve code readability.&lt;/p&gt;
&lt;p&gt;If you are anything like me a few years ago, you might confuse it with pattern matching in Regex.&lt;/p&gt;
&lt;p&gt;Even a quick Google search of ‘pattern matching’ without any other context brings you content that’s pretty close to that definition.&lt;/p&gt;
&lt;p&gt;Formally, pattern matching is the process of checking any data (be it a sequence of characters, a series of tokens, a tuple, or anything else) against other data.&lt;/p&gt;
&lt;p&gt;In terms of programming, depending on the capabilities of the language, this could mean any of the following:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Matching against an expected data type&lt;/li&gt;
&lt;li&gt;Matching against an expected hash structure (e.g. presence of specific keys)&lt;/li&gt;
&lt;li&gt;Matching against an expected array length&lt;/li&gt;
&lt;li&gt;Assigning the matches (or a part of them) to some variables&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My first foray into pattern matching was through Elixir. Elixir has &lt;a href=&quot;https://elixir-lang.org/getting-started/pattern-matching.html&quot;&gt;first class support&lt;/a&gt; for pattern matching, so much so that the &lt;code class=&quot;language-text&quot;&gt;=&lt;/code&gt; operator is in fact the &lt;code class=&quot;language-text&quot;&gt;match&lt;/code&gt; operator, rather than simple assignment.&lt;/p&gt;
&lt;p&gt;This means that in Elixir, the following is actually valid code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;iex&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
iex&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; x&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With that in mind, let’s look at the new pattern matching support for Ruby 2.7+ and how we can use it to make our code more readable, starting from today.&lt;/p&gt;
&lt;h2&gt;Ruby Pattern Matching with &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Ruby supports pattern matching with a special &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt; expression. The syntax is:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;expression&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pattern1&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pattern2&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is not to be confused with the &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;when&lt;/code&gt; expression. &lt;code class=&quot;language-text&quot;&gt;when&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt; branches cannot be mixed in a single &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you do not provide an &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt; expression, any failing match will raise a &lt;code class=&quot;language-text&quot;&gt;NoMatchingPatternError&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Pattern Matching Arrays in Ruby&lt;/h3&gt;
&lt;p&gt;Pattern matching can be used to match arrays to pre-required structures against data types, lengths or values.&lt;/p&gt;
&lt;p&gt;For example, all of the following are matches (note that only the first &lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt; will be evaluated, as &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt; stops looking after the first match):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Three&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Three&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# because * is a spread operator that matches anything&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# and the value of the variable a is now 1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;A pattern matching clause like this is very useful when you want to produce multiple signals from a method call.&lt;/p&gt;
&lt;p&gt;In the Elixir world, this is frequently used when performing operations that could have both an &lt;code class=&quot;language-text&quot;&gt;:ok&lt;/code&gt; result and an &lt;code class=&quot;language-text&quot;&gt;:error&lt;/code&gt; result, for example, inserted into a database.&lt;/p&gt;
&lt;p&gt;Here is how we can use it for better readability:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;create&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; save&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model_params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    render &lt;span class=&quot;token symbol&quot;&gt;:json&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; model
  &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; errors&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    render &lt;span class=&quot;token symbol&quot;&gt;:json&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; errors
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Somewhere in your code, e.g. inside a global helper or your model base class (with a different name).&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;save&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;attrs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  model &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Model&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;attrs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Pattern Matching Objects in Ruby&lt;/h3&gt;
&lt;p&gt;You can also match objects in Ruby to enforce a specific structure:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# By default, all object matches are partial&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# and is same as {a: Integer}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# and the value of variable a is now 1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# and the value of variable a is now 1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# and the value of variable b is now 2&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;does not match&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# This will match only if the object has a and no other keys&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This works great when imposing strong rules for matching against any params.&lt;/p&gt;
&lt;p&gt;For example, if you are writing a fancy greeter, it could have the following (strongly opinionated) structure:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;greet&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; hash
  &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; first_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; first_name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; last_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; last_name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;first_name&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;last_name&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    puts &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;greeting&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;name&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; greeting&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Anonymous&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
    greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Anonymous&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

greet &lt;span class=&quot;token comment&quot;&gt;# Hello, Anonymous&lt;/span&gt;
greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Hello, John&lt;/span&gt;
greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;first_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; last_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Doe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Hello, John Doe&lt;/span&gt;
greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Bonjour&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; first_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; last_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Doe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Bonjour, John Doe&lt;/span&gt;
greet&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;greeting&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Bonjour&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Bonjour, Anonymous&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Variable Binding and Pinning in Ruby&lt;/h3&gt;
&lt;p&gt;As we have seen in some of the above examples, pattern matching is really useful to assign part of the patterns to arbitrary variables.
This is called variable binding, and there are several ways we can bind to a variable:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;With a strong type match, e.g. &lt;code class=&quot;language-text&quot;&gt;in [Integer =&amp;gt; a]&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;in {a: Integer =&amp;gt; a}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Without the type specification, e.g. &lt;code class=&quot;language-text&quot;&gt;in [a, 1, 2]&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;in {a: a}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Without the variable name, which defaults to using the key name, e.g. &lt;code class=&quot;language-text&quot;&gt;in {a:}&lt;/code&gt; will define a variable named &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt; with the value at key &lt;code class=&quot;language-text&quot;&gt;a&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Bind rest, e.g. &lt;code class=&quot;language-text&quot;&gt;in [Integer, *rest]&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;in {a: Integer, **rest}&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;How, then, can we match when we want to use an existing variable as a sub-pattern? This is when we can use variable &lt;em&gt;pinning&lt;/em&gt; with the &lt;code class=&quot;language-text&quot;&gt;^&lt;/code&gt; (pin) operator:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can even use this when a variable is defined in a pattern itself, allowing you to write powerful patterns like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; order
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;billing_address&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shipping_address&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  puts &lt;span class=&quot;token string&quot;&gt;&quot;both billing and shipping are to the same city&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;both billing and shipping must be to the same city&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One important quirk to mention with variable binding is that even if the pattern doesn’t fully match, the variable will still have been bound.
This can sometimes be useful.&lt;/p&gt;
&lt;p&gt;But, in most cases, this could also be a cause of subtle bugs - so make sure that you don’t rely on shadowed variable values that have been used inside a match.
For example, in the following, you would expect the city to be “Amsterdam”, but it would instead be “Berlin”:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;city &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Amsterdam&quot;&lt;/span&gt;
order &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;billing_address&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Berlin&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shipping_address&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Zurich&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; order
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;billing_address&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; shipping_address&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;^&lt;/span&gt;city&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  puts &lt;span class=&quot;token string&quot;&gt;&quot;both billing and shipping are to the same city&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  puts &lt;span class=&quot;token string&quot;&gt;&quot;both billing and shipping must be to the same city&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
puts city &lt;span class=&quot;token comment&quot;&gt;# Berlin instead of Amsterdam&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Matching Ruby’s Custom Classes&lt;/h3&gt;
&lt;p&gt;You can implement some special methods to make custom classes pattern matching aware in Ruby.&lt;/p&gt;
&lt;p&gt;For example, to pattern match a user against his &lt;code class=&quot;language-text&quot;&gt;first_name&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;last_name&lt;/code&gt;, we can define &lt;code class=&quot;language-text&quot;&gt;deconstruct_keys&lt;/code&gt; on the class:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;deconstruct_keys&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;keys&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;first_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; first_name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; last_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; last_name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; user
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;first_name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;John&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  puts &lt;span class=&quot;token string&quot;&gt;&quot;Hey, John&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;keys&lt;/code&gt; argument to &lt;code class=&quot;language-text&quot;&gt;deconstruct_keys&lt;/code&gt; contains the keys that have been requested in the pattern.
This is a way for the receiver to provide only the required keys if computing all of them is expensive.&lt;/p&gt;
&lt;p&gt;In the same way as &lt;code class=&quot;language-text&quot;&gt;deconstruct_keys&lt;/code&gt;, we could provide an implementation of &lt;code class=&quot;language-text&quot;&gt;deconstruct&lt;/code&gt; to allow objects to be pattern matched as an array.
For example, let’s say we have a &lt;code class=&quot;language-text&quot;&gt;Location&lt;/code&gt; class that has latitude and longitude. In addition to using &lt;code class=&quot;language-text&quot;&gt;deconstruct_keys&lt;/code&gt; to provide latitude and longitude keys, we could expose an array in the form of &lt;code class=&quot;language-text&quot;&gt;[latitude, longitude]&lt;/code&gt; as well:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Location&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;deconstruct&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;latitude&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; longitude&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; location
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Float&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; latitude&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Float&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; longitude&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  puts &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;latitude&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;, &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;longitude&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Using Guards for Complex Patterns&lt;/h3&gt;
&lt;p&gt;If we have complex patterns that cannot be represented with regular pattern match operators, we can also use an &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; (or &lt;code class=&quot;language-text&quot;&gt;unless&lt;/code&gt;) statement to provide a guard for the match:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;matches&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&quot;no match&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Pattern Matching with &lt;code class=&quot;language-text&quot;&gt;=&amp;gt;&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt; Without &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;If you are on Ruby 3+, you have access to even more pattern matching magic. Starting from Ruby 3, pattern matching can be done in a single line without a case statement:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Three&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; one&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; two&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; three&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
puts one &lt;span class=&quot;token comment&quot;&gt;# 1&lt;/span&gt;
puts two &lt;span class=&quot;token comment&quot;&gt;# 2&lt;/span&gt;
puts three &lt;span class=&quot;token comment&quot;&gt;# Three&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# Same as above&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Three&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Integer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; one&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; two&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; three&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Given that the above syntax does not have an &lt;code class=&quot;language-text&quot;&gt;else&lt;/code&gt; clause, it is most useful when the data structure is known beforehand.&lt;/p&gt;
&lt;p&gt;As an example, this pattern could fit well inside a base controller that allows only admin users:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AdminController&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;AuthenticatedController&lt;/span&gt;
  before_action &lt;span class=&quot;token symbol&quot;&gt;:verify_admin&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;verify_admin&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;role&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:admin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;rescue&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;NoMatchingPatternError&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;NotAllowedError&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Pattern Matching in Ruby: Watch This Space&lt;/h2&gt;
&lt;p&gt;At first, pattern matching can feel a bit strange to grasp.
To some, it might feel like glorified object/array deconstruction.&lt;/p&gt;
&lt;p&gt;But if the popularity of Elixir is any indication, pattern matching is a great tool to have in your arsenal.
And having first-hand experience with using it on Elixir, I can confirm that it is hard to live without once you get used to it.&lt;/p&gt;
&lt;p&gt;If you are on Ruby 2.7, pattern matching (with &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt;) is still experimental. With Ruby 3, &lt;code class=&quot;language-text&quot;&gt;case&lt;/code&gt;/&lt;code class=&quot;language-text&quot;&gt;in&lt;/code&gt; has moved to stable while the newly introduced single-line pattern matching expressions are experimental.
Warnings can be turned off with &lt;code class=&quot;language-text&quot;&gt;Warning[:experimental] = false&lt;/code&gt; in code or &lt;code class=&quot;language-text&quot;&gt;-W:no-experimental&lt;/code&gt; command-line key.&lt;/p&gt;
&lt;p&gt;Even though pattern matching in Ruby is still in its early stages, I hope you’ve found this introduction useful and that you’re as excited as I am about future developments to come!&lt;/p&gt;
&lt;hr style=&quot;width:100%; margin-bottom:0px;&quot;/&gt;
&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href=&quot;https://blog.appsignal.com/2021/07/28/introduction-to-pattern-matching-in-ruby.html&quot;&gt;AppSignal Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr style=&quot;width:100%; margin-top:0px;&quot;/&gt;</content:encoded></item><item><title><![CDATA[What's new in Rails 7]]></title><description><![CDATA[Rails 7 was released on December 15. Basecamp, HEY, Github, and Shopify have all been running the Rails 7 alpha in production, so we can expect the release to be pretty stable. In this post, we will look at some of the biggest new features and changes that Rails 7 brings.]]></description><link>https://pulkitgoyal.inwhats-new-in-rails-7</link><guid isPermaLink="false">https://pulkitgoyal.inwhats-new-in-rails-7</guid><pubDate>Wed, 15 Dec 2021 10:57:37 GMT</pubDate><content:encoded>&lt;p&gt;&lt;del&gt;Rails 7 is just around the corner. We don’t have a confirmed release date, but it is expected to be &lt;a href=&quot;https://twitter.com/rafaelfranca/status/1467974458015158273&quot;&gt;available before Christmas&lt;/a&gt;, so not very long to go.
The latest version as of this post’s publication is &lt;code class=&quot;language-text&quot;&gt;7.0.0.rc1&lt;/code&gt;, the first release candidate.
Basecamp, HEY, Github, and Shopify have all been running the Rails 7 alpha in production, so we can expect even the release candidate to be pretty stable.&lt;/del&gt;&lt;/p&gt;
&lt;p&gt;Rails 7 was &lt;a href=&quot;https://rubyonrails.org/2021/12/15/Rails-7-fulfilling-a-vision&quot;&gt;released&lt;/a&gt; on December 15.&lt;/p&gt;
&lt;p&gt;In this post, we will look at some of the new features and changes that Rails 7 will bring.&lt;/p&gt;
&lt;h2&gt;Node and Webpack Not Required&lt;/h2&gt;
&lt;p&gt;Yes, you read that right! JavaScript in Rails 7 will no longer require NodeJS or Webpack. And you can still use npm packages.&lt;/p&gt;
&lt;p&gt;Transpiling ES6 with Babel and bundling with Webpack require a lot of setup. While Rails supported it pretty well with the &lt;code class=&quot;language-text&quot;&gt;Webpacker&lt;/code&gt; gem, this brings a lot of baggage, is hard to understand and make any changes to, especially while maintaining upgradability.&lt;/p&gt;
&lt;p&gt;The default for new apps created with &lt;code class=&quot;language-text&quot;&gt;rails new&lt;/code&gt; is now to use import maps through the &lt;a href=&quot;https://github.com/rails/importmap-rails/&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;importmaps-rails&lt;/code&gt; gem&lt;/a&gt;.
Instead of writing a &lt;code class=&quot;language-text&quot;&gt;package.json&lt;/code&gt; and installing dependencies with &lt;code class=&quot;language-text&quot;&gt;npm&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;yarn&lt;/code&gt;, you use &lt;code class=&quot;language-text&quot;&gt;./bin/importmap&lt;/code&gt; CLI to pin (or unpin or update) dependencies.&lt;/p&gt;
&lt;p&gt;For example, to install date-fns:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ ./bin/importmap pin date-fns&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will add a line in &lt;code class=&quot;language-text&quot;&gt;config/importmap.rb&lt;/code&gt; like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;pin &lt;span class=&quot;token string&quot;&gt;&quot;date-fns&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://ga.jspm.io/npm:date-fns@2.27.0/esm/index.js&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In your JavaScript code, you can continue using everything like you used to:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; formatDistance&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; subDays &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;date-fns&apos;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;formatDistance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subDays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; addSuffix&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//=&gt; &quot;3 days ago&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;One thing to keep in mind with this setup is that there is no transpiling between what you write and what the browser gets. For the most part, this is ok since all browsers that matter now support ES6 out of the box.&lt;/p&gt;
&lt;p&gt;But this also means that you won’t be able to use TypeScript or jsx because they require transpilation to JS before use.&lt;/p&gt;
&lt;p&gt;So, if you want to use React with JSX, you still have to fall back to a different setup (using webpack/rollup/esbuild).&lt;/p&gt;
&lt;p&gt;Rails 7 can do this for you. All you need is one command with your chosen strategy:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ ./bin/rails javascript:install:[esbuild|rollup|webpack]&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Turbolinks and UJS Replaced by Turbo and Stimulus&lt;/h2&gt;
&lt;p&gt;Applications generated with Rails 7 will get Turbo and Stimulus (from Hotwire) by default, instead of Turbolinks and UJS. &lt;a href=&quot;https://hotwired.dev/&quot;&gt;Hotwire is a new approach that delivers fast updates to the DOM&lt;/a&gt; by sending HTML over the wire.&lt;/p&gt;
&lt;h2&gt;Encryption at Database Layer&lt;/h2&gt;
&lt;p&gt;Rails 7 allows marking certain database fields as encrypted using the &lt;code class=&quot;language-text&quot;&gt;encrypts&lt;/code&gt; method on &lt;code class=&quot;language-text&quot;&gt;ActiveRecord::Base&lt;/code&gt;. This means that after an &lt;a href=&quot;https://edgeguides.rubyonrails.org/active_record_encryption.html#setup&quot;&gt;initial setup&lt;/a&gt;, you can write code like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ApplicationRecord&lt;/span&gt;
  encrypts &lt;span class=&quot;token symbol&quot;&gt;:text&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can continue using the encrypted attributes like you would any other attribute. Rails 7 will encrypt and decrypt it automatically between the database and your application.&lt;/p&gt;
&lt;p&gt;But this comes with a slight quirk: you cannot query the database by that field unless you pass a &lt;code class=&quot;language-text&quot;&gt;deterministic: true&lt;/code&gt; option to the &lt;code class=&quot;language-text&quot;&gt;encrypts&lt;/code&gt; method.
The deterministic mode is less secure than the default non-deterministic mode, so only use it for attributes you absolutely need to query.&lt;/p&gt;
&lt;h2&gt;Asynchronous Querying&lt;/h2&gt;
&lt;p&gt;There is now a &lt;code class=&quot;language-text&quot;&gt;load_async&lt;/code&gt; method that you can use when querying data to fetch results in the background. This is especially important when you need to load several un-related queries from a controller action. You can run:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;PostsController&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;index&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token variable&quot;&gt;@posts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load_async
    &lt;span class=&quot;token variable&quot;&gt;@categories&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Category&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load_async
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will fire both queries in the background at the same time. So, if each query takes 200ms, the total time spent fetching the data is ~200ms instead of 400ms, if they are fetched serially.&lt;/p&gt;
&lt;h2&gt;Zeitwerk Mode for Rails 7&lt;/h2&gt;
&lt;p&gt;This is a breaking change for older applications that still run the classic loader. All Rails 7 applications must use Zeitwerk mode, but the switch is pretty easy. &lt;a href=&quot;https://edgeguides.rubyonrails.org/classic_to_zeitwerk_howto.html&quot;&gt;Check out the full Zeitwerk upgrade guide&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Other Rails 7 Updates&lt;/h2&gt;
&lt;h3&gt;Retry Jobs Unlimited Times&lt;/h3&gt;
&lt;p&gt;ActiveJob now allows passing &lt;code class=&quot;language-text&quot;&gt;:unlimited&lt;/code&gt; as the &lt;code class=&quot;language-text&quot;&gt;attempts&lt;/code&gt; parameter on &lt;code class=&quot;language-text&quot;&gt;retry_on&lt;/code&gt;. Rails will continue to attempt the job without any maximum number of attempts.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyJob&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveJob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
  retry_on&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AlwaysRetryException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attempts&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:unlimited&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;perform&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;KABOOM&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Named Variants&lt;/h3&gt;
&lt;p&gt;You can now name variants on &lt;code class=&quot;language-text&quot;&gt;ActiveStorage&lt;/code&gt; instead of specifying size on every access.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;User&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ApplicationRecord&lt;/span&gt;
  has_one_attached &lt;span class=&quot;token symbol&quot;&gt;:avatar&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;attachable&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    attachable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;variant &lt;span class=&quot;token symbol&quot;&gt;:thumb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resize&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;100x100&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;#Call avatar.variant(:thumb) to get a thumb variant of an avatar:&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; image_tag user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;avatar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;variant&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:thumb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Hash to HTML Attributes&lt;/h3&gt;
&lt;p&gt;There is a new &lt;code class=&quot;language-text&quot;&gt;tag.attributes&lt;/code&gt; method for use in views that translates a hash into HTML attributes:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;erb&quot;&gt;&lt;pre class=&quot;language-erb&quot;&gt;&lt;code class=&quot;language-erb&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token erb language-erb&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;&amp;lt;%=&lt;/span&gt; tag&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attributes&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; aria&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; label&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Search&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token delimiter punctuation&quot;&gt;%&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;will produce&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;aria-label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Search&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Ruby &lt;code class=&quot;language-text&quot;&gt;debug&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;The new default for debugging has changed from &lt;code class=&quot;language-text&quot;&gt;byebug&lt;/code&gt; to the &lt;a href=&quot;https://edgeguides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;debug&lt;/code&gt; gem&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Instead of calling &lt;code class=&quot;language-text&quot;&gt;byebug&lt;/code&gt;, you now need to call &lt;code class=&quot;language-text&quot;&gt;debugger&lt;/code&gt; in the code to enter a debugging session.&lt;/p&gt;
&lt;h3&gt;Assert a Single Record with &lt;code class=&quot;language-text&quot;&gt;sole&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;When querying records, you can now call &lt;code class=&quot;language-text&quot;&gt;sole&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;find_sole_by&lt;/code&gt; (instead of &lt;code class=&quot;language-text&quot;&gt;first&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;find_by&lt;/code&gt;) when you want to assert that the query should only match a single record.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;Product&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;price = %?&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; price&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sole
&lt;span class=&quot;token comment&quot;&gt;# =&gt; ActiveRecord::RecordNotFound      (if no Product with given price)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# =&gt; #&amp;lt;Product ...&gt;                    (if one Product with given price)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# =&gt; ActiveRecord::SoleRecordExceeded  (if more than one Product with given price)&lt;/span&gt;

user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api_keys&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;find_sole_by&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# as above&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Check Presence / Absence of an Association&lt;/h3&gt;
&lt;p&gt;We can now use &lt;code class=&quot;language-text&quot;&gt;where.associated(:association)&lt;/code&gt; to check if an association is present on a record instead of joining and checking for the existence of an id.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Before:&lt;/span&gt;
account&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;users&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;joins&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:contact&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;not&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;contact_id&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# After:&lt;/span&gt;
account&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;users&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;associated&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:contact&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Stream Generated Files from Controller Actions&lt;/h3&gt;
&lt;p&gt;You can now use &lt;code class=&quot;language-text&quot;&gt;send_stream&lt;/code&gt; inside a controller action to start streaming a file that is being generated on the fly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;send_stream&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;filename&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;subscribers.csv&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;stream&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
  stream&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write &lt;span class=&quot;token string&quot;&gt;&quot;email_address,updated_at\n&quot;&lt;/span&gt;

  &lt;span class=&quot;token variable&quot;&gt;@subscribers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;find_each &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;subscriber&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    stream&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;write &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;subscriber&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email_address&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;,&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;subscriber&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;updated_at&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;\n&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This provides an immediate (partial) response to the user so that they know something is happening and has an added benefit if you deploy on Heroku.&lt;/p&gt;
&lt;p&gt;Since the file will start streaming immediately, &lt;a href=&quot;https://devcenter.heroku.com/articles/request-timeout#long-polling-and-streaming-responses&quot;&gt;Heroku will not terminate the connection&lt;/a&gt;.
This means you don’t need to resort to background jobs to generate one-off files that take longer than 30 seconds.&lt;/p&gt;
&lt;h2&gt;Upgrading to Rails 7&lt;/h2&gt;
&lt;p&gt;As with previous versions of Rails, upgrading is simple. While we don’t have an official upgrade guide yet, the steps will remain the same:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Change the Rails version number in the Gemfile (&lt;code class=&quot;language-text&quot;&gt;7.0.0.rc1&lt;/code&gt; as of the publication date) and run &lt;code class=&quot;language-text&quot;&gt;bundle update&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run &lt;code class=&quot;language-text&quot;&gt;bundle exec rails app:update&lt;/code&gt;. Follow the interactive CLI and add/replace/modify the files as required.&lt;/li&gt;
&lt;li&gt;Run your tests and verify everything works as expected.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Wrap up&lt;/h2&gt;
&lt;p&gt;You can see the full list of bug fixes, features, and changes in the &lt;a href=&quot;https://edgeguides.rubyonrails.org/7_0_release_notes.html&quot;&gt;Rails 7 release notes&lt;/a&gt;.
These are not comprehensive at the moment, but we can expect them to be updated soon.&lt;/p&gt;
&lt;p&gt;If you are still running Rails 6 or lower, please note that with the final release of Rails 7, Rails 6.1 will enter the “security issues only” mode and will no longer receive bug fixes.
This will also mark the EOL for Rails 5.2, as it will no longer receive any fixes.&lt;/p&gt;
&lt;p&gt;Have fun coding!&lt;/p&gt;
&lt;hr style=&quot;width:100%; margin-bottom:0px;&quot;/&gt;
&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href=&quot;https://blog.appsignal.com/2021/12/15/whats-new-in-rails7.html&quot;&gt;AppSignal Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr style=&quot;width:100%; margin-top:0px;&quot;/&gt;</content:encoded></item><item><title><![CDATA[Testing WebSocket Clients in Elixir with a Mock Server]]></title><description><![CDATA[In this post we will discuss about a very high level overview of implementing a long running connection between two services with the use of WebSocket and then writing unit tests for the functionality.]]></description><link>https://pulkitgoyal.in/testing-websocket-clients-in-elixir-with-a-mock-server</link><guid isPermaLink="false">https://pulkitgoyal.in/testing-websocket-clients-in-elixir-with-a-mock-server</guid><pubDate>Sun, 01 Aug 2021 06:14:58 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAwABBf/EABUBAQEAAAAAAAAAAAAAAAAAAAAB/9oADAMBAAIQAxAAAAHgqSKdkn//xAAZEAEAAgMAAAAAAAAAAAAAAAACABADEhP/2gAIAQEAAQUCnNa0sjVf/8QAFhEAAwAAAAAAAAAAAAAAAAAAEBEh/9oACAEDAQE/AYh//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAGRAAAgMBAAAAAAAAAAAAAAAAARAAAhEh/9oACAEBAAY/ApuF9sV//8QAGxABAAICAwAAAAAAAAAAAAAAAQARECExQVH/2gAIAQEAAT8hC+JuXA7DAo2NMBph5j//2gAMAwEAAgADAAAAEPjP/8QAGBEAAgMAAAAAAAAAAAAAAAAAARARITH/2gAIAQMBAT8QFk6v/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPxA//8QAGxABAAICAwAAAAAAAAAAAAAAARExABAhgZH/2gAIAQEAAT8QRwMYBYkwdujSgpMJCVJ481//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Testing Websocket Clients in Elixir with a Mock Server&quot;
        title=&quot;&quot;
        src=&quot;/static/8455ba73d4e0eca75beb5e68398d37c8/6a068/image.jpg&quot;
        srcset=&quot;/static/8455ba73d4e0eca75beb5e68398d37c8/09b79/image.jpg 240w,
/static/8455ba73d4e0eca75beb5e68398d37c8/7cc5e/image.jpg 480w,
/static/8455ba73d4e0eca75beb5e68398d37c8/6a068/image.jpg 960w,
/static/8455ba73d4e0eca75beb5e68398d37c8/e5166/image.jpg 1200w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  &lt;/p&gt;
&lt;div align=&quot;center&quot;&gt;
  Image from &lt;a href=&quot;https://blog.appsignal.com/2021/06/22/how-to-test-websocket-clients-in-elixir-with-a-mock-server.html&quot; target=&quot;_blank&quot;&gt;AppSignal Blog&lt;/a&gt;
&lt;/div&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;In this post we will discuss about a very high level overview of implementing a long running connection between two services with the use of WebSocket and then writing unit tests for the functionality.&lt;/p&gt;
&lt;p&gt;The WebSocket protocol allows a two-way communication between two channels.
Most developers would know it as a fast, near real-time communication medium between the client and the server.
In the Phoenix and Elixir world, many would recognize it from LiveView or Channels which are abstractions built on top of fast realtime transports, usually a WebSocket.&lt;/p&gt;
&lt;p&gt;But another area that WebSocket is a great communication medium for is an app built on the Microservices architecture.
Let’s say we have an e-commerce application that uses (among others) two services:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; - Create and manage the user’s orders&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; - Processing the payments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When a user makes a purchase, the &lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; service would create an order corresponding to the purchase and send it to the &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; service.
This service could then respond with a payment page URL which the user then needs to visit to complete his payment.
After the completion, the &lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; service needs to create an invoice for the order and send it to the user, so it will need a way to watch for the completion of payments.&lt;/p&gt;
&lt;p&gt;For such an architecture, a long running connection between &lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; through a WebSocket is a great choice as both services can interchange messages and notify the other service about updates or events.&lt;/p&gt;
&lt;h2&gt;WebSocket Client&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://hexdocs.pm/websockex/readme.html&quot;&gt;WebSockex&lt;/a&gt; is a library to implement a WebSocket client in Elixir. A very simplified implementation of the client as it could look on the &lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; service can be &lt;a href=&quot;https://gist.github.com/pulkit110/b8fe73fe7db7f424bcb3a88f89806ff7#file-payments_client-ex&quot;&gt;found here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The client behaves as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It is started as a process with a URL of the &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; WebSocket Server and some details about the &lt;code class=&quot;language-text&quot;&gt;order&lt;/code&gt; it needs to process.&lt;/li&gt;
&lt;li&gt;As soon as it is connected, it sends a message to the &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; service to initiate the payment process.&lt;/li&gt;
&lt;li&gt;At some point (normally soon after the payment has been initialized), the &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; service responds with a list of available payment methods for the order.&lt;/li&gt;
&lt;li&gt;The client selects the first payment method and asks &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; to initiate payment with that method.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; sends a message with the payment page url that the &lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; service can use to initiate a payment on the web app.&lt;/li&gt;
&lt;li&gt;At some point, &lt;code class=&quot;language-text&quot;&gt;Payments&lt;/code&gt; sends a message to the client informing about the state of the transaction, e.g. &lt;code class=&quot;language-text&quot;&gt;FULFILL&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;CANCEL&lt;/code&gt; etc.&lt;/li&gt;
&lt;li&gt;If the payment is &lt;code class=&quot;language-text&quot;&gt;FULFILL&lt;/code&gt;, fulfill the order. If the payment is &lt;code class=&quot;language-text&quot;&gt;CANCEL&lt;/code&gt;, cancel the order and close the connection.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Testing External Services&lt;/h2&gt;
&lt;p&gt;Now that we have a working WebSocket client in place, the next question is how do we test it?
It connects to an external service (even though this service is ultimately controlled by us, but this is still external in terms of the &lt;code class=&quot;language-text&quot;&gt;Orders&lt;/code&gt; service).
There are several solutions for writing tests that interact with external services:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a separate service for the API Client and Stub out those requests with  &lt;a href=&quot;https://github.com/dashbitco/mox&quot;&gt;Mox&lt;/a&gt; from José Valim.&lt;/li&gt;
&lt;li&gt;Mock out the requests during the tests with a library like &lt;a href=&quot;https://github.com/jjh42/mock&quot;&gt;Mock&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Roll out your own web server to handle the requests.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;All these methods and their pros and cons have been covered in detail in several posts in the community.
One that I particularly like and recommend is &lt;a href=&quot;https://medium.com/flatiron-labs/rolling-your-own-mock-server-for-testing-in-elixir-2cdb5ccdd1a0&quot;&gt;Testing External Web Requests in Elixir?&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We will discuss how to write tests for our above client by rolling out our own server during the tests.&lt;/p&gt;
&lt;h2&gt;Mock Server&lt;/h2&gt;
&lt;p&gt;To test out the client, we first need to create a Mock Server that will be able to provide a connection to this client and interact with it.
We will use &lt;a href=&quot;https://github.com/elixir-plug/plug_cowboy&quot;&gt;plug and cowboy&lt;/a&gt; to create the server and control the socket.&lt;/p&gt;
&lt;h3&gt;Mock HTTP Server&lt;/h3&gt;
&lt;p&gt;First, since we might need many of these servers running in parallel during the tests, we will need a way to generate ports so that the servers don’t collide.
This can be done by starting an &lt;code class=&quot;language-text&quot;&gt;Agent&lt;/code&gt; that starts randomly at a port and then assigns us a port incrementally during the tests&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; get_port &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; Process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;whereis&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__MODULE__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; start_ports_agent&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  Agent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_and_update&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__MODULE__&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;port&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; port &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; start_ports_agent &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  Agent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; Enum&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50_000&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;63_000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name:&lt;/span&gt; __MODULE__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The Mock Server now needs to obtain a port, start listening on that port for connections.
On each new client connection, we will open a socket (which we will see later).
This is the server side socket that is linked with the client side socket being opened from our WebSocket client implementation.
This socket is running in its own process, so in order for our test code to interact with it, we will need to obtain its PID inside the tests.
Since the tests only know about the HTTP Server and not the socket, we will send the Socket PID back to the server so we can retrieve it from the test code.
&lt;a href=&quot;https://gist.github.com/pulkit110/b8fe73fe7db7f424bcb3a88f89806ff7#file-mock_websocket_server-ex&quot;&gt;Here&lt;/a&gt; is how the Mock Server code looks (I know it is a bit complex, so don’t be alarmed, it is easy to understand once we see the socket).&lt;/p&gt;
&lt;p&gt;The usage of the above server is very simple:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Start the server:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;server_ref&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Commerce&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Orders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MockWebsocketServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
on_exit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; Commerce&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Orders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MockWebsocketServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shutdown&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server_ref&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;Connect the client using the url from above.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If you need to send messages to the client, first obtain the server pid&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;server_pid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Commerce&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Orders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MockWebsocketServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;receive_socket_pid&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Send Messages to the server that will relay them to the client. Check &lt;code class=&quot;language-text&quot;&gt;Commerce.Orders.TestSocket.websocket_info/2&lt;/code&gt; for all possible clauses&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;send&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server_pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; frame&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;This server also sends all messages that it receives to the owner process. This means that to verify that the server has received a message, you can use&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;assert_receive on the &lt;span class=&quot;token attr-name&quot;&gt;owner:&lt;/span&gt;
assert_receive&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;SOME MESSAGE&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Mock Socket&lt;/h3&gt;
&lt;p&gt;The next thing after creating the mock server is to create the actual server side socket that will handle the connections.
This is the &lt;code class=&quot;language-text&quot;&gt;Commerce.Orders.TestSocket&lt;/code&gt; to which our mock HTTP server dispatches the initial connection to.&lt;/p&gt;
&lt;p&gt;The full code for the test socket can be found &lt;a href=&quot;https://gist.github.com/pulkit110/b8fe73fe7db7f424bcb3a88f89806ff7#file-test_socket-ex&quot;&gt;here&lt;/a&gt;. Let’s break this down.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;init&lt;/code&gt; is what is called after the &lt;code class=&quot;language-text&quot;&gt;MockWebsocketServer&lt;/code&gt; is started and it receives a new connection request from our WebSocket client (that we want to test).
You can check out the full &lt;a href=&quot;https://ninenines.eu/docs/en/cowboy/2.5/manual/cowboy_websocket/&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;cowboy_websocket&lt;/code&gt; documentation&lt;/a&gt; for more details about the supported responses.
&lt;code class=&quot;language-text&quot;&gt;[{test_pid, agent_pid}]&lt;/code&gt; is the initial state that we sent out from the &lt;code class=&quot;language-text&quot;&gt;MockWebsocketServer.dispatch&lt;/code&gt; and we will keep track of that in state to manage sending of frames to the socket.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;websocket_init&lt;/code&gt; is called once the connection is upgraded to WebSocket and this is where we send own (i.e. the Server Socket’s) &lt;code class=&quot;language-text&quot;&gt;pid&lt;/code&gt; to the &lt;code class=&quot;language-text&quot;&gt;MockWebsocketServer&lt;/code&gt; which the test code can then retrieve using &lt;code class=&quot;language-text&quot;&gt;receive_socket_pid&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;websocket_handle&lt;/code&gt; is called for every frame received.
This is where we further process the received frame to verify messages from our client.
If this differs between different WebSocket clients that we want to test, you could skip the call to &lt;code class=&quot;language-text&quot;&gt;handle_websocket_message&lt;/code&gt; and it’s implementations and just use &lt;code class=&quot;language-text&quot;&gt;send(state.pid, to_string(msg))&lt;/code&gt; to send all messages to the test process.
The test process can then verify the frames as required.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;websocket_info&lt;/code&gt; is called for every Erlang message that the process receives.
This is what we will be using to receive messages from the test code to trigger certain events from the Server Socket.
The first argument to this function could be anything that the test code sends, so you can add as many clauses as you would like to support to simulate certain events.
Here we are interested in only initiating a &lt;code class=&quot;language-text&quot;&gt;close&lt;/code&gt; from the test code or sending a particular frame to the client socket.&lt;/p&gt;
&lt;h2&gt;Test Code&lt;/h2&gt;
&lt;p&gt;Now that we have the WebSocket client and the Mock Server and Mock Socket out of the way, we can get to the actual test code that will test the WebSocket client using the Mocks.&lt;/p&gt;
&lt;p&gt;To start the server in our tests, we will use &lt;code class=&quot;language-text&quot;&gt;MockWebsocketServer.start&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;setup &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;server_ref&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MockWebsocketServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;self&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  on_exit&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt; MockWebsocketServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shutdown&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server_ref&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;url:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;server_ref:&lt;/span&gt; server_ref&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s test out our client with the mock server in place.
Instead of several smaller tests that test a single part of the client, I am writing a big test case that describes the full interaction for the sake of describing all available testing options without too much boilerplate code.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;test &lt;span class=&quot;token string&quot;&gt;&quot;interacts with the server&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;url:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;order:&lt;/span&gt; order&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pid&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; WebSocketClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start_link&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;url:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  server_pid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MockWebsocketServer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;receive_socket_pid&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# A payment is initiated immediately after a connection&lt;/span&gt;
  assert_receive Jason&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;initiate_payment:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# WebSocket client receives the payment methods from the server (from the hard coded message response). We do not need any code for this since we generalized it directly in the socket.&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# The payment is initiated with credit card&lt;/span&gt;
  assert_receive Jason&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;initiate_payment:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;credit_card&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# Send a FULFILL state from the server. This is the alternative to hard coded messages in the server side socket.&lt;/span&gt;
  send&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;server_pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Jason&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FULFILL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# Confirm that the order was fulfilled&lt;/span&gt;
  assert &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Order&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;FULFILL&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Orders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get_order&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;order&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Wrap-up&lt;/h2&gt;
&lt;p&gt;In this post we touched briefly on a sample Microservices architecture, how we could use WebSockets to communicate between different services and finally saw a very simplified implementation of a WebSocket client using &lt;code class=&quot;language-text&quot;&gt;WebSockex&lt;/code&gt;.
If you are looking for a more complex &lt;code class=&quot;language-text&quot;&gt;WebSockex&lt;/code&gt; client example, I recommend &lt;a href=&quot;https://sapandiwakar.in/stomp-over-a-websocket-client-in-elixir/&quot;&gt;this post&lt;/a&gt; which walks through building a complete STOMP client with WebSocket.&lt;/p&gt;
&lt;p&gt;While it took some work to set up our mock server and socket for testing our WebSocket clients, it makes our testing really smooth and simple.
If we add another WebSocket client later, we could utilize the same server to unit-test the new client without any complex setup or mocking.&lt;/p&gt;
&lt;p&gt;In addition to this, we now have tests that do not depend on any implementation details of the client.
We are just testing business logic rather than implementation or tying our test code to specific libraries being used in the implementation.
So if you were to replace the WebSocket client implementation to use &lt;a href=&quot;https://github.com/ninenines/gun&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;gun&lt;/code&gt;&lt;/a&gt; instead of &lt;code class=&quot;language-text&quot;&gt;WebSockex&lt;/code&gt;, we wouldn’t need to change anything in our tests.
In fact, our tests would serve as an additional validation point for this migration to see that everything keeps working like it did before.&lt;/p&gt;
&lt;hr style=&quot;width:100%; margin-bottom:0px;&quot;/&gt;
&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href=&quot;https://blog.appsignal.com/2021/06/22/how-to-test-websocket-clients-in-elixir-with-a-mock-server.html&quot;&gt;AppSignal Blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;hr style=&quot;width:100%; margin-top:0px;&quot;/&gt;</content:encoded></item><item><title><![CDATA[Monitoring Application Email Delivery]]></title><description><![CDATA[Monitor all emails being sent by your app and retry based on WebHook notifications about failures.]]></description><link>https://pulkitgoyal.in/monitoring-application-email-delivery-with-mailgun</link><guid isPermaLink="false">https://pulkitgoyal.in/monitoring-application-email-delivery-with-mailgun</guid><pubDate>Sun, 02 May 2021 06:14:58 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/ca6c8efc42134031fa2f3352ac02aac8/93719/envelope.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAEEAgP/xAAUAQEAAAAAAAAAAAAAAAAAAAAE/9oADAMBAAIQAxAAAAHvBtJGywGv/8QAGxAAAQQDAAAAAAAAAAAAAAAAAgABERIDEBP/2gAIAQEAAQUCyU4iMKhPtyhf/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAEDQQIUIv/aAAgBAwEBPwFyvLmjXjtn/8QAGhEAAgIDAAAAAAAAAAAAAAAAAAECAxIUQf/aAAgBAgEBPwGNeKNmziP/xAAXEAEBAQEAAAAAAAAAAAAAAAABIRAg/9oACAEBAAY/AgjkOP/EABoQAAIDAQEAAAAAAAAAAAAAAAABESExUUH/2gAIAQEAAT8hVkOKZ02KzQZhMOYkqV4f/9oADAMBAAIAAwAAABD/AC//xAAZEQACAwEAAAAAAAAAAAAAAAABIQARYfD/2gAIAQMBAT8QWEqgEKJfZP/EABkRAQEBAAMAAAAAAAAAAAAAAAERACFh8P/aAAgBAgEBPxC1GvLlWhPd7//EABwQAQEAAgMBAQAAAAAAAAAAAAERADEhQVFhcf/aAAgBAQABPxBa2SEFHanmHXBTyzZ5gHzKsuQEAfmMiAOnvBYLEO5M/9k=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;envelope&quot;
        title=&quot;&quot;
        src=&quot;/static/ca6c8efc42134031fa2f3352ac02aac8/6a068/envelope.jpg&quot;
        srcset=&quot;/static/ca6c8efc42134031fa2f3352ac02aac8/09b79/envelope.jpg 240w,
/static/ca6c8efc42134031fa2f3352ac02aac8/7cc5e/envelope.jpg 480w,
/static/ca6c8efc42134031fa2f3352ac02aac8/6a068/envelope.jpg 960w,
/static/ca6c8efc42134031fa2f3352ac02aac8/644c5/envelope.jpg 1440w,
/static/ca6c8efc42134031fa2f3352ac02aac8/0f98f/envelope.jpg 1920w,
/static/ca6c8efc42134031fa2f3352ac02aac8/93719/envelope.jpg 4000w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;h2&gt;Email Delivery Services&lt;/h2&gt;
&lt;p&gt;If you have ever used Mailgun or another similar email delivery service like SendGrid etc with a shared IP pool, you would have noticed that some emails are occasionally blocked even though your own spam rate is very low or zero. This usually happens because someone else assigned on the same shared IP as yours has been abusing the services by sending spam emails and the IP has been blacklisted. While Mailgun and SendGrid do actively trace and resolve these issues, but this still means that you are missing emails to your users, and if all you are sending are transactional emails that have high value to the users, this will affect their confidence in the service.&lt;/p&gt;
&lt;p&gt;The easiest way to tackle these issues is to opt for a dedicated IP from the service providers. You would then be in control of your IP reputation and can avoid such issues in the future if you are sending good emails.&lt;/p&gt;
&lt;p&gt;But a dedicated IP does not make sense for all teams. You might be starting a new project or have a very limited amounts of emails to deliver even on an already established product. In this case, it might be better to roll out your own email monitoring system, especially since it is very easy to manage and maintain.&lt;/p&gt;
&lt;h2&gt;Email Monitoring&lt;/h2&gt;
&lt;p&gt;The main use case of our monitoring solution is to track email failures and retry the email (which might obtain a new IP from the shared pool and thereby avoid the blacklisting). In case we are experiencing repeated failures, it might be a good idea to be notified so that we can manually intervene.&lt;/p&gt;
&lt;p&gt;While all of this can be done in any framework, since I had recently the need for it in an Elixir/Phoenix app, that is what I will describe. I will be assuming &lt;a href=&quot;https://github.com/thoughtbot/bamboo&quot;&gt;Bamboo&lt;/a&gt; as our email library but this should again work even if you are using &lt;a href=&quot;https://github.com/swoosh/swoosh&quot;&gt;Swoosh&lt;/a&gt; or another library.&lt;/p&gt;
&lt;h3&gt;Email Schema&lt;/h3&gt;
&lt;p&gt;The first step is to create a schema to track all emails that you are queueing from the application. Let’s call it &lt;code class=&quot;language-text&quot;&gt;MyApp.Communication.Email&lt;/code&gt;. Since this step will probably be different for a lot of apps, I will just give a very brief list of the fields I have considered for the schema.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;schema &lt;span class=&quot;token string&quot;&gt;&quot;emails&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  field &lt;span class=&quot;token atom symbol&quot;&gt;:attempt_at&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:utc_datetime&lt;/span&gt;
  field &lt;span class=&quot;token atom symbol&quot;&gt;:attempt_count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:integer&lt;/span&gt;
  field &lt;span class=&quot;token atom symbol&quot;&gt;:mailgun_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:string&lt;/span&gt;
  field &lt;span class=&quot;token atom symbol&quot;&gt;:mailgun_url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:string&lt;/span&gt;
  field &lt;span class=&quot;token atom symbol&quot;&gt;:delivered_recipients&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  embeds_one &lt;span class=&quot;token atom symbol&quot;&gt;:last_delivery_status&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DeliveryStatus&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;on_replace:&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:delete&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    field &lt;span class=&quot;token atom symbol&quot;&gt;:code&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:integer&lt;/span&gt;
    field &lt;span class=&quot;token atom symbol&quot;&gt;:message&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:string&lt;/span&gt;
    field &lt;span class=&quot;token atom symbol&quot;&gt;:attempt_no&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:integer&lt;/span&gt;
    field &lt;span class=&quot;token atom symbol&quot;&gt;:description&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:string&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  timestamps&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Feel free to add or remove the fields as per your needs.&lt;/p&gt;
&lt;h3&gt;Tracking Queued Emails&lt;/h3&gt;
&lt;p&gt;The next step is to configure the &lt;code class=&quot;language-text&quot;&gt;Mailer&lt;/code&gt; to add your own method that will track the email after it has been queued to Mailgun.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token attribute variable&quot;&gt;@doc&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&quot;
Delivers an email immediately and tracks its delivery.
&quot;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; deliver_now_with_tracking!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; deliver_now&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;response:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      raise error
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token attribute variable&quot;&gt;@doc&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&quot;
Queues an email for delivery and tracks its delivery.
&quot;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; deliver_later_with_tracking&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;no email&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; deliver_later_with_tracking&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; Mix&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:test&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
      deliver_now_with_tracking!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
    Task&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Supervisor&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start_child&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Bamboo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;TaskSupervisor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      deliver_now_with_tracking!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I assume this is pretty self explanatory. In addition to Bamboo’s &lt;code class=&quot;language-text&quot;&gt;deliver_now!&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;deliver_later&lt;/code&gt;, we now have two more methods that allow to track the email.  The only thing of note here is we are passing &lt;code class=&quot;language-text&quot;&gt;response: true&lt;/code&gt; to Bamboo’s deliver methods to obtain the raw response from Mailgun. Mailgun responds with a json in the format &lt;code class=&quot;language-text&quot;&gt;{&amp;quot;id&amp;quot;: &amp;quot;&amp;lt;message_id&amp;gt;&amp;quot;}&lt;/code&gt;. Here is our tracking code that just creates a new &lt;code class=&quot;language-text&quot;&gt;Email&lt;/code&gt; entry in the database:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;id&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Communication&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;mailgun_id:&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trim_leading&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trim_trailing&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;attempt_count:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;attempt_at:&lt;/span&gt; Timex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;now&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;body:&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;status_code:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Jason&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decode&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Bamboo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Email&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; Mix&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;body:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;{\&quot;id\&quot;: \&quot;&amp;lt;ID@mx.domain.ch&gt;\&quot;}&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;status_code:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; track_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; Logger&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;debug&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to track email. Response not recognized - &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;inspect&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Receiving Mailgun Notifications&lt;/h3&gt;
&lt;p&gt;The next step is to create a controller that receives notifications from Mailgun through Webhook. I will leave out the router configuration since that will vary from app to app. Just keep in mind that you will need to use a pipeline that DOES NOT contain &lt;code class=&quot;language-text&quot;&gt;protect_from_forgery&lt;/code&gt; as the requests are originating from Mailgun which will not have that info.&lt;/p&gt;
&lt;p&gt;Mailgun notifications are formatted like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;signature&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;&quot;token&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;timestamp&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;123&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token property&quot;&gt;&quot;signature&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;event-data&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;event&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;delivered|failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;message&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;&quot;headers&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;&quot;message-id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;recipient&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;delivery-status&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;storage&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;&quot;url&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;xx&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Inside the controller, there are two main aspects to responding to Mailgun notifications.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Verify the signature: Here is how you can compute the signature on your app. You need to verify this with the signature that Mailgun sends in the json payload .&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; compute_signature&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;token&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; timestamp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:sha256&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:crypto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hmac&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mailgun_webhook_signing_key&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; token &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&gt;&lt;/span&gt; timestamp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; Base&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode16&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;case:&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:lower&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Handle the event: This is where things get interesting. We are only going to track the &lt;code class=&quot;language-text&quot;&gt;delivered&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;failed&lt;/code&gt; events as these are the most interesting ones for us.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; handle_event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;event&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;delivered&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;recipient&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; recipient&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Email&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; Communication&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;update_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;recipient:&lt;/span&gt; recipient&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; handle_event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;event&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;failed&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;delivery-status&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;storage&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;url&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;recipient&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; recipient&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;Email&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; retryable?&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    attrs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;last_delivery_status:&lt;/span&gt; status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;attempt_at:&lt;/span&gt; Timex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;now&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; Timex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shift&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;minutes:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:math&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pow&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attempt_count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; floor&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;mailgun_url:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;to:&lt;/span&gt; recipient
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    Communication&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;retry_email&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attrs&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
    title &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; MyAppWeb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Gettext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dgettext&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;emails&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Email Delivery Abandoned&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    MyAppWeb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AdminEmail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;email_alert&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; MyAppWeb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Mailer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deliver_later&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; email&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;defp&lt;/span&gt; handle_event&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _email&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;do:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:not_acceptable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here, if the email is delivered, we just add the recipient to our tracked email.
If the email is undelivered, we do a check if this is one of the emails that we want to retry (a simple logic could be to retry all emails with status between 500 and 554 and less than 5 attempts.&lt;/p&gt;
&lt;p&gt;If it is, we retry it with an exponential duration or discard it and send an alert email to the admin so that he can manually intervene and check on it.&lt;/p&gt;
&lt;p&gt;Now, to our final step. How do we retry the email. Mailgun makes it really simple. Each email has a unique storage URL (this is the &lt;code class=&quot;language-text&quot;&gt;mailgun_url&lt;/code&gt; that we tracked on our email model). We can post to that URL with some form data to re-enqueue the email with new details. Here is a simple method on the mailer that does this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token attribute variable&quot;&gt;@doc&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&quot;
Schedules an email on Mailgun. Requires:
  * url - Mailgun Storage URL (like https://storage.eu.mailgun.net/v3/domains/mg.domain.ch/messages/BASE64KEY)
  * datetime - UTC Date Time to schedule
  * to - Recipient Address
Returns the raw response from Mailgun.

## Examples:
    iex&gt; schedule_mailgun_email([api_key: &quot;foo&quot;], %{url: &quot;xyz&quot;, datetime: ~U[], to: &quot;some@example.com&quot;})
    %{body: &quot;{\&quot;id\&quot;: \&quot;&amp;lt;ID@mx.domain.ch&gt;\&quot;}&quot;}
&quot;&quot;&quot;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; schedule_mailgun_email!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;url:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;datetime:&lt;/span&gt; datetime&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;to:&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  auth_key &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Base&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;encode64&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;api:&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&gt;&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;api_key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  HTTPoison&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;post!&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:form&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;to&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;o:deliverytime&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; datetime &lt;span class=&quot;token operator&quot;&gt;|&gt;&lt;/span&gt; Timex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_unix&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;Authorization:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Basic &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter punctuation&quot;&gt;#{&lt;/span&gt;auth_key&lt;span class=&quot;token delimiter punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token attr-name&quot;&gt;ssl:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:versions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;:&lt;span class=&quot;token string&quot;&gt;&apos;tlsv1.2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;follow_redirect:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With this system in place, you are ready to configure Mailgun to send webhook notifications (this can be configured from the Dashboard -&gt; Sending -&gt; Webhook)  to your app and you would be ready to automatically track and retry any failed emails.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Elixir Pooling with Poolboy]]></title><description><![CDATA[Creating a pool of processes cannot get easier in Elixir.]]></description><link>https://pulkitgoyal.inelixir-pooling-with-poolboy</link><guid isPermaLink="false">https://pulkitgoyal.inelixir-pooling-with-poolboy</guid><pubDate>Sun, 18 Apr 2021 09:42:58 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2a92dcc9475a2238dd97e374b6d0f567/93719/pool.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAEDAv/EABcBAAMBAAAAAAAAAAAAAAAAAAABAwT/2gAMAwEAAhADEAAAAc0g7YUAL//EABcQAQEBAQAAAAAAAAAAAAAAAAEQAjH/2gAIAQEAAQUCOuIl/8QAFREBAQAAAAAAAAAAAAAAAAAAARD/2gAIAQMBAT8BJ//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8BP//EABgQAAIDAAAAAAAAAAAAAAAAAAAgMUGB/9oACAEBAAY/ApL1f//EABoQAQADAAMAAAAAAAAAAAAAAAEAESEQQZH/2gAIAQEAAT8hAgaXKhTB64s2+oZl3Fn/2gAMAwEAAgADAAAAECcf/8QAFxEBAQEBAAAAAAAAAAAAAAAAAQARMf/aAAgBAwEBPxBAcsv/xAAVEQEBAAAAAAAAAAAAAAAAAAABEP/aAAgBAgEBPxBn/8QAGRABAQEBAQEAAAAAAAAAAAAAAREAIUGB/9oACAEBAAE/EJPKlXLFPUB8ZZrIhF5cE0o710WBv//Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;pool&quot;
        title=&quot;&quot;
        src=&quot;/static/2a92dcc9475a2238dd97e374b6d0f567/6a068/pool.jpg&quot;
        srcset=&quot;/static/2a92dcc9475a2238dd97e374b6d0f567/09b79/pool.jpg 240w,
/static/2a92dcc9475a2238dd97e374b6d0f567/7cc5e/pool.jpg 480w,
/static/2a92dcc9475a2238dd97e374b6d0f567/6a068/pool.jpg 960w,
/static/2a92dcc9475a2238dd97e374b6d0f567/644c5/pool.jpg 1440w,
/static/2a92dcc9475a2238dd97e374b6d0f567/0f98f/pool.jpg 1920w,
/static/2a92dcc9475a2238dd97e374b6d0f567/93719/pool.jpg 4000w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/devinus/poolboy&quot;&gt;Poolboy&lt;/a&gt; is a generic pooling library for Erlang (ergo Elixir). Since it is originally made for Erlang, you wouldn’t find a great set of documentation around how to use it on Elixir apps, and especially with Phoenix apps. If you know your way around Erlang, you can follow the wonderful documentation on their readme. If not, this post will try to explain just the basics of how you could get started and include this in your project.&lt;/p&gt;
&lt;p&gt;First things first, do you need pooling? If you are spinning up processes that could take a while to run, you could soon run into a problem where there is a huge wave of processes being spinned up without the previous ones finishing and thereby exhausting all your system resources. BEAM is great at distributing work across the processes and it will try to do its best, but even it is limited by system resources. This is where Poolboy comes in.&lt;/p&gt;
&lt;p&gt;The installation is simple, something like &lt;code class=&quot;language-text&quot;&gt;{:poolboy, &amp;quot;~&amp;gt; 1.5&amp;quot;}&lt;/code&gt; in your &lt;code class=&quot;language-text&quot;&gt;mix.exs&lt;/code&gt; would normally be enough. Now, in order to use Poolboy, you would first need to identify the resource that you need to pool. If you have a static module that you spin up to perform some task, e.g. an open connection to a database (all of the following is imaginary code), something like the following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Processor &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arg1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; connection&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DBConnection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;open&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		DBConnection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;do_something&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;connection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are two big issues with the above code.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You are opening a new connection to the DB whenever you want to process something.&lt;/li&gt;
&lt;li&gt;If you have 1000s of requests at the same time, you might soon run out of memory if your DB does not allow that many simultaneous connections.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This is of course an imaginary situation and most DB libraries out there would probably manage this for you. But this could be extended to any number of use cases, for example, opening a &lt;a href=&quot;https://github.com/fazibear/export&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ErlPort&lt;/code&gt;&lt;/a&gt; to a ruby process and communicating with it.&lt;/p&gt;
&lt;p&gt;Let’s see how we can pool this operation. First, we will need to make the module stateful. The easiest way to do that is to create an &lt;a href=&quot;https://elixir-lang.org/getting-started/mix-otp/agent.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Agent&lt;/code&gt;&lt;/a&gt;. Let’s see how the agent would look like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProcessorAgent &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; start_link&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_params&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
    Agent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;start_link&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; connection&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; DBConnection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;open&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      connection
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
		Agent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;get&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; connection &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      DBConnection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;do_something&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;connection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Simple enough, right? We create a new state in start_link and then whenever we need to process something, we get the agent from it’s PID and do something with the connection (that is the state of the agent). We can now update our original &lt;code class=&quot;language-text&quot;&gt;Processor&lt;/code&gt; to use this agent instead of directly opening a new connection.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;defmodule&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Processor &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; process&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;arg1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
		&lt;span class=&quot;token atom symbol&quot;&gt;:poolboy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;transaction&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:processor_agent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; pid &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
      MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProcessorAgent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pid&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arg2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This uses the &lt;code class=&quot;language-text&quot;&gt;:poolboy.transaction/3&lt;/code&gt; to use a checkout a process from a pool and run the processing logic inside that. You might be wondering what is special about the &lt;code class=&quot;language-text&quot;&gt;:processor_agent&lt;/code&gt; atom. Nothing, this is just a name that we give to the process pool when starting our application. In &lt;code class=&quot;language-text&quot;&gt;application.ex&lt;/code&gt;, do the following inside your &lt;code class=&quot;language-text&quot;&gt;start/2&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;elixir&quot;&gt;&lt;pre class=&quot;language-elixir&quot;&gt;&lt;code class=&quot;language-elixir&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; start&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; _args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	children &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;# ...&lt;/span&gt;
		&lt;span class=&quot;token atom symbol&quot;&gt;:poolboy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;child_spec&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:processor_agent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; processor_poolboy_config&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; processor_poolboy_config&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
		&lt;span class=&quot;token attr-name&quot;&gt;name:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token atom symbol&quot;&gt;:local&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token atom symbol&quot;&gt;:processor_agent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token attr-name&quot;&gt;worker_module:&lt;/span&gt; MyApp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ProcessorAgent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
		&lt;span class=&quot;token attr-name&quot;&gt;size:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Initial number of workers&lt;/span&gt;
		&lt;span class=&quot;token attr-name&quot;&gt;max_overflow:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;# Extra workers (auto-stopped after work) to spawn if under load&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are a few other options to configure Poolboy. Now that you know how the interface with Elixir should look like, I will leave you to explore the &lt;a href=&quot;https://github.com/devinus/poolboy#options&quot;&gt;configuration options on Poolboy&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Hosting NextJS projects on Heroku with SSL]]></title><description><![CDATA[Deploy custom SSL certificate to Heroku for Next.JS apps and auto redirect to https.]]></description><link>https://pulkitgoyal.in/ssl-nextjs-deployment-on-heroku</link><guid isPermaLink="false">https://pulkitgoyal.in/ssl-nextjs-deployment-on-heroku</guid><pubDate>Sat, 13 Mar 2021 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/440d0a041724fe4ea62d7b38b96a3b08/857b3/image.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFwAAAwEAAAAAAAAAAAAAAAAAAAIEAf/EABUBAQEAAAAAAAAAAAAAAAAAAAAC/9oADAMBAAIQAxAAAAG1XhmrDQ//xAAaEAADAAMBAAAAAAAAAAAAAAABAgMAERIT/9oACAEBAAEFArMOJbYaY401oJsevNM//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAwEBPwE//8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAHRAAAgICAwEAAAAAAAAAAAAAAAECESIxAxIhcf/aAAgBAQAGPwLdDne2ZSo6y+k+OOKR6rZ//8QAGxABAAMBAAMAAAAAAAAAAAAAAQARITFBYbH/2gAIAQEAAT8hMWxstIwR4c9EO2ZlWSgNj4Z2O1deT7cs/9oADAMBAAIAAwAAABD43//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQMBAT8QP//EABQRAQAAAAAAAAAAAAAAAAAAABD/2gAIAQIBAT8QP//EABoQAQADAQEBAAAAAAAAAAAAAAEAESExkUH/2gAIAQEAAT8QDgKUbE0o+7Xs6LyrDdz7LRx4SwMYMugKsaaPI+WN6aaK3nOxYHI1ys//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;image&quot;
        title=&quot;&quot;
        src=&quot;/static/440d0a041724fe4ea62d7b38b96a3b08/6a068/image.jpg&quot;
        srcset=&quot;/static/440d0a041724fe4ea62d7b38b96a3b08/09b79/image.jpg 240w,
/static/440d0a041724fe4ea62d7b38b96a3b08/7cc5e/image.jpg 480w,
/static/440d0a041724fe4ea62d7b38b96a3b08/6a068/image.jpg 960w,
/static/440d0a041724fe4ea62d7b38b96a3b08/644c5/image.jpg 1440w,
/static/440d0a041724fe4ea62d7b38b96a3b08/0f98f/image.jpg 1920w,
/static/440d0a041724fe4ea62d7b38b96a3b08/857b3/image.jpg 6000w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;I am part of a team where we are building a NextJS web app and not long ago, we were looking for deployment options. Since most of our infrastructure is on Heroku, this was the obvious first choice for us since the team had had good experience with it in the fast and we wanted to focus on keeping the dev-ops to a minimum. The main requirements for our app were that we were going to be using wildcard domains and we absolutely needed SSL for the app.&lt;/p&gt;
&lt;p&gt;If there was a single domain, Heroku is pretty straightforward as SSL and automatic SSL redirects work out of the box. For our use-case however, even though Heroku does provide wildcard SSL certificates with their automated SSL management, it was prohibitively expensive to obtain one. So we wanted to use an external certificate for the website. Setting up external certificates is pretty easy on Heroku, but unfortunately, it doesn’t provide automatic SSL redirects. So if a user lands on the &lt;code class=&quot;language-text&quot;&gt;http&lt;/code&gt; page, you either have to resort to client side redirects (for this, by the way, &lt;a href=&quot;https://www.npmjs.com/package/react-https-redirect&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;react-https-redirect&lt;/code&gt;&lt;/a&gt; is one of the easiest to set up) or fiddle with the buildpack configuration to enable automatic redirects.&lt;/p&gt;
&lt;p&gt;We decided to go with the second approach, by using the &lt;a href=&quot;https://github.com/heroku/heroku-buildpack-nginx&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;nginx-buildpack&lt;/code&gt;&lt;/a&gt; on top of the &lt;code class=&quot;language-text&quot;&gt;heroku/nodejs&lt;/code&gt; buildpack that we used to build the NextJS app. First step, add the buildpack to your app:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ heroku buildpacks:add heroku-community/nginx&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For what we wanted to achieve, we would need the “Customizable NGINX config” feature from the buildpack. Here is how our &lt;code class=&quot;language-text&quot;&gt;config/nginx.config.erb&lt;/code&gt; looks like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;daemon off;
# Heroku dynos have at least 4 cores.
worker_processes &amp;lt;%= ENV[&amp;#39;NGINX_WORKERS&amp;#39;] || 4 %&amp;gt;;

events {
	use epoll;
	accept_mutex on;
	worker_connections &amp;lt;%= ENV[&amp;#39;NGINX_WORKER_CONNECTIONS&amp;#39;] || 1024 %&amp;gt;;
}

http {
	gzip on;
	gzip_comp_level 2;
	gzip_min_length 512;

	server_tokens off;

	log_format l2met &amp;#39;measure#nginx.service=$request_time request_id=$http_x_request_id&amp;#39;;
	access_log &amp;lt;%= ENV[&amp;#39;NGINX_ACCESS_LOG_PATH&amp;#39;] || &amp;#39;logs/nginx/access.log&amp;#39; %&amp;gt; l2met;
	error_log &amp;lt;%= ENV[&amp;#39;NGINX_ERROR_LOG_PATH&amp;#39;] || &amp;#39;logs/nginx/error.log&amp;#39; %&amp;gt;;

	include mime.types;
	default_type application/octet-stream;
	sendfile on;

	# Must read the body in 5 seconds.
	client_body_timeout 5;

	server {
		listen &amp;lt;%= ENV[&amp;quot;PORT&amp;quot;] %&amp;gt;;
		server_name _;
		keepalive_timeout 5;

		location / {

      &amp;lt;% if ENV[&amp;#39;NGINX_SKIP_HTTPS_PROXY&amp;#39;] == &amp;#39;true&amp;#39; %&amp;gt;
        if ($http_x_forwarded_proto != &amp;quot;https&amp;quot;) {
          return 301 https://$host$request_uri;
        }
      &amp;lt;% end %&amp;gt;

			proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header Host $http_host;
			proxy_redirect off;
			proxy_pass http://localhost:3000; #next serve listens here and receives nginx requests
		}
	}
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All other portions of this config are pretty straightforward. The main part where the magic happens is this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;location / {

  &amp;lt;% if ENV[&amp;#39;NGINX_SKIP_HTTPS_PROXY&amp;#39;] == &amp;#39;true&amp;#39; %&amp;gt;
    if ($http_x_forwarded_proto != &amp;quot;https&amp;quot;) {
      return 301 https://$host$request_uri;
    }
  &amp;lt;% end %&amp;gt;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header Host $http_host;
  proxy_redirect off;
  proxy_pass http://localhost:3000; #next serve listens here and receives nginx requests
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This catches all paths accessed on the &lt;code class=&quot;language-text&quot;&gt;http&lt;/code&gt; protocol, we redirect with a 301 to the corresponding path on &lt;code class=&quot;language-text&quot;&gt;https&lt;/code&gt;. This is where things get interesting. Even with the https protocol, Heroku always forwards the request to the http block since &lt;a href=&quot;https://devcenter.heroku.com/articles/http-routing#heroku-headers&quot;&gt;under the hood, Heroku router (over)writes the X-Forwarded-Proto and the X-Forwarded-Port request headers&lt;/a&gt;. So, if the header value of &lt;code class=&quot;language-text&quot;&gt;X-Forwarded-Proto&lt;/code&gt;, we should not redirect and instead set up a &lt;code class=&quot;language-text&quot;&gt;reverse-proxy&lt;/code&gt; to our deployed app.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Conditional global stylesheets for Next.js apps]]></title><description><![CDATA[Serve different stylesheets to different parts of your Next.js apps]]></description><link>https://pulkitgoyal.in/conditional-global-stylesheets-for-nextjs-apps</link><guid isPermaLink="false">https://pulkitgoyal.in/conditional-global-stylesheets-for-nextjs-apps</guid><pubDate>Sun, 01 Nov 2020 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/90dfaed4c6253fc3477188c5f9198741/80c67/image.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 66.66666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAEC/8QAFwEAAwEAAAAAAAAAAAAAAAAAAAEEBf/aAAwDAQACEAMQAAABxZItIGf/xAAWEAADAAAAAAAAAAAAAAAAAAABECD/2gAIAQEAAQUCRj//xAAVEQEBAAAAAAAAAAAAAAAAAAAAEf/aAAgBAwEBPwFH/8QAFBEBAAAAAAAAAAAAAAAAAAAAEP/aAAgBAgEBPwE//8QAFBABAAAAAAAAAAAAAAAAAAAAIP/aAAgBAQAGPwJf/8QAGRABAAIDAAAAAAAAAAAAAAAAAAERECEx/9oACAEBAAE/IVpbxSev/9oADAMBAAIAAwAAABC3L//EABURAQEAAAAAAAAAAAAAAAAAABAR/9oACAEDAQE/EIP/xAAWEQEBAQAAAAAAAAAAAAAAAAABABH/2gAIAQIBAT8Qhcv/xAAXEAEBAQEAAAAAAAAAAAAAAAAAARGB/9oACAEBAAE/ENTDbhiRak//2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;image&quot;
        title=&quot;&quot;
        src=&quot;/static/90dfaed4c6253fc3477188c5f9198741/6a068/image.jpg&quot;
        srcset=&quot;/static/90dfaed4c6253fc3477188c5f9198741/09b79/image.jpg 240w,
/static/90dfaed4c6253fc3477188c5f9198741/7cc5e/image.jpg 480w,
/static/90dfaed4c6253fc3477188c5f9198741/6a068/image.jpg 960w,
/static/90dfaed4c6253fc3477188c5f9198741/644c5/image.jpg 1440w,
/static/90dfaed4c6253fc3477188c5f9198741/0f98f/image.jpg 1920w,
/static/90dfaed4c6253fc3477188c5f9198741/80c67/image.jpg 3500w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://nextjs.org/&quot;&gt;Next.js&lt;/a&gt; gives you the best developer experience with all the features you need for production: hybrid static &amp;#x26; server rendering, TypeScript support, smart bundling, route pre-fetching, and more. No config needed. The out of the box CSS support is amazing. It means that you could just put your css/scss files that you obtained from the designer at &lt;code class=&quot;language-text&quot;&gt;styles/scss/app.scss&lt;/code&gt; (the path or the file name don’t matter) and add the following into your &lt;code class=&quot;language-text&quot;&gt;_app.tsx&lt;/code&gt; (or your &lt;code class=&quot;language-text&quot;&gt;_app.jsx&lt;/code&gt;).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../styles/scss/app.scss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This sets everything up including the compilation of SCSS files and hot reloading of the styles whenever you make some changes.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;But the shortcoming with this approach is that this import needs to be inside the global &lt;code class=&quot;language-text&quot;&gt;_app&lt;/code&gt; file. You cannot import it inside individual pages if you need to separate styles by page (or have a different stylesheet for some of the pages in your app). A common use case for this feature is if your app has two components, an admin interface where special users could perform some operations on your domain objects and a public interface which is visible to everyone else. Of course, you could ask the designer to provide a global stylesheet that works for both parts of the interface, but that is not always possible (and unnecessarily wasteful).&lt;/p&gt;
&lt;h2&gt;Styled JSX (and Babel and Webpack Configuration)&lt;/h2&gt;
&lt;p&gt;This is where Next.js’s &lt;a href=&quot;https://github.com/vercel/styled-jsx&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;styled-jsx&lt;/code&gt;&lt;/a&gt; support comes in. Bear in mind, it isn’t exactly meant to solve this issue, but it works great nonetheless. First start by installing the required packages (not that you don’t need &lt;code class=&quot;language-text&quot;&gt;sass&lt;/code&gt; related plugins if you have a CSS stylesheet):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;yarn add styled-jsx @types/styled-jsx styled-jsx-plugin-sass node-sass-middleware sass&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next you need to configure babel for &lt;code class=&quot;language-text&quot;&gt;styled-jsx&lt;/code&gt; (again, you don’t need the sass specific stuff if you have only the CSS). Make sure your &lt;code class=&quot;language-text&quot;&gt;.babelrc&lt;/code&gt; looks something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;{
  &amp;quot;presets&amp;quot;: [
    [
      &amp;quot;next/babel&amp;quot;,
      {
        &amp;quot;styled-jsx&amp;quot;: {
          &amp;quot;plugins&amp;quot;: [
            [ &amp;quot;styled-jsx-plugin-sass&amp;quot;, { &amp;quot;sassOptions&amp;quot;: { &amp;quot;includePaths&amp;quot;: [&amp;quot;./styles&amp;quot;] } }]
          ]
        }
      }
    ]
  ]
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now configure webpack (the config lives inside &lt;code class=&quot;language-text&quot;&gt;next.config.js&lt;/code&gt;) to allow loading css and scss files with the &lt;code class=&quot;language-text&quot;&gt;styled-jsx/webpack&lt;/code&gt; loader.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;webpack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;config&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defaultLoaders &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rules&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      test&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;/\.(scss|css)$/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      use&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        defaultLoaders&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;babel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          loader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;styled-jsx/webpack&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;loader&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;global&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; config&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;The Style Component&lt;/h2&gt;
&lt;p&gt;Now we are ready to use the stylesheets inside our app. All we need is import the styles from the respective files and provide them through a regular react component.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; publicStyles &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../../../styles/public.scss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; adminStyles &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;../../../styles/admin.scss&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;AdminStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReactElement &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;jsx&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;{adminStyles}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;PublicStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReactElement &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;jsx&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;global&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;{publicStyles}&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;AppStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; admin &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; admin&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReactElement &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;admin&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AdminStyles&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;PublicStyles&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can now include this component as a part of your App exported from &lt;code class=&quot;language-text&quot;&gt;_app.tsx&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;tsx&quot;&gt;&lt;pre class=&quot;language-tsx&quot;&gt;&lt;code class=&quot;language-tsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pageProps &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ReactElement &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; router &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRouter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; isAdmin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; router&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pathname&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;/admin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Component&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token spread&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;pageProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AppStyles&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;admin&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;isAdmin&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Authentication Using GraphQL Ruby]]></title><description><![CDATA[Handle authentication right from your GraphQL API using login and logout mutations.]]></description><link>https://pulkitgoyal.in/authentication-using-graphql-ruby</link><guid isPermaLink="false">https://pulkitgoyal.in/authentication-using-graphql-ruby</guid><pubDate>Mon, 12 Oct 2020 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/05e850a47a2a09dad93630f421cc571d/93719/image.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 62.916666666666664%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAANABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAwAB/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAH/2gAMAwEAAhADEAAAAS0DHlk//8QAGRABAAMBAQAAAAAAAAAAAAAAAgABAxEx/9oACAEBAAEFAstLjd8JUC4fJmuV/8QAFhEBAQEAAAAAAAAAAAAAAAAAABFB/9oACAEDAQE/AcR//8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAIAQIBAT8BV//EABoQAAMBAAMAAAAAAAAAAAAAAAABESECQXH/2gAIAQEABj8Clw1tnZDkqP0//8QAGhABAQEAAwEAAAAAAAAAAAAAAREAIUFhUf/aAAgBAQABPyEZE+fuZDJ7lDa56cwCRdEJXJkF63//2gAMAwEAAgADAAAAEHQf/8QAFhEBAQEAAAAAAAAAAAAAAAAAEQAB/9oACAEDAQE/EDRG/8QAFhEAAwAAAAAAAAAAAAAAAAAAEBEh/9oACAECAQE/EHR//8QAGhABAQEBAQEBAAAAAAAAAAAAAREhAEFhUf/aAAgBAQABPxDUEqxuM5rDDhgL6acmXjK04o/0D4crg27JavnCkwlv3v/Z&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;image&quot;
        title=&quot;&quot;
        src=&quot;/static/05e850a47a2a09dad93630f421cc571d/6a068/image.jpg&quot;
        srcset=&quot;/static/05e850a47a2a09dad93630f421cc571d/09b79/image.jpg 240w,
/static/05e850a47a2a09dad93630f421cc571d/7cc5e/image.jpg 480w,
/static/05e850a47a2a09dad93630f421cc571d/6a068/image.jpg 960w,
/static/05e850a47a2a09dad93630f421cc571d/644c5/image.jpg 1440w,
/static/05e850a47a2a09dad93630f421cc571d/0f98f/image.jpg 1920w,
/static/05e850a47a2a09dad93630f421cc571d/93719/image.jpg 4000w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;I often get asked questions about how to implement an authentication system for use in a frontend app relying wholly on GraphQL. There are divided opinions on whether you should keep authentication separate from the GraphQL API. To be honest, I don’t see a reason to do that. If you do authentication through a controller reached through a REST API or through the GraphQL Schema, it hardly makes any difference and if the frontend relies heavily on GraphQL, I don’t see a reason not to have the authentication part with it too.&lt;/p&gt;
&lt;h2&gt;Separating GraphQL Schema&lt;/h2&gt;
&lt;p&gt;The first thing to handling authentication through GraphQL is serve two different Schemas based on whether the user is making authenticated requests or a non-authenticated one. It is also the simplest one to take care of, so let’s get this out of the way.&lt;/p&gt;
&lt;p&gt;If you are using graphql-ruby, you might already have something along the lines of the following in your &lt;code class=&quot;language-text&quot;&gt;GraphQLController&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;execute_query&lt;/span&gt;&lt;/span&gt;
  schema&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;execute&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:document&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;token symbol&quot;&gt;:variables&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@variables&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;token symbol&quot;&gt;:context&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                  &lt;span class=&quot;token symbol&quot;&gt;:operation_name&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@operation_name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_json
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All we need is to provide that schema class based on whether the user is currently logged in. Something like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;schema&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token variable&quot;&gt;@schema&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Current&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user
                &lt;span class=&quot;token constant&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;AuthenticatedSchema&lt;/span&gt;
              &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
                &lt;span class=&quot;token constant&quot;&gt;Schema&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PublicSchema&lt;/span&gt;
              &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just define the schema classes as separate classes inheriting from &lt;a href=&quot;https://graphql-ruby.org/schema/definition&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;GraphQL::Schema&lt;/code&gt;&lt;/a&gt; and you are done.&lt;/p&gt;
&lt;h2&gt;Public Schema and Auth Mutations&lt;/h2&gt;
&lt;p&gt;The first question we need to ask ourselves is what authentication is in terms of our app? For us, it is a mutation that creates a new &lt;code class=&quot;language-text&quot;&gt;UserSession&lt;/code&gt; on the backend. So the &lt;code class=&quot;language-text&quot;&gt;PublicSchema&lt;/code&gt; boils down to a single mutation:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Schema&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PublicSchema&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;GraphQL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Schema&lt;/span&gt;
    mutation &lt;span class=&quot;token constant&quot;&gt;Types&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PublicMutationType&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Types&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PublicMutationType&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BaseObject&lt;/span&gt;
    description &lt;span class=&quot;token string&quot;&gt;&quot;Public Mutation API&quot;&lt;/span&gt;

    field &lt;span class=&quot;token symbol&quot;&gt;:login&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:mutation&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Mutations&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Login&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can add more operations if you need to support sign up, account recovery options etc. But once we can figure out the login part, the rest could be derived pretty easily.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Mutations&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Login&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
    graphql_name &lt;span class=&quot;token string&quot;&gt;&quot;Login&quot;&lt;/span&gt;

    argument &lt;span class=&quot;token symbol&quot;&gt;:email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:required&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    argument &lt;span class=&quot;token symbol&quot;&gt;:password&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:required&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    argument &lt;span class=&quot;token symbol&quot;&gt;:remember_token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:required&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;

    field &lt;span class=&quot;token symbol&quot;&gt;:session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;UserSessionType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    field &lt;span class=&quot;token symbol&quot;&gt;:errors&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:remember_token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;present&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
        user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;find_by&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:persistence_token&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; args&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:remember_token&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        user_session &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;UserSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;present&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
        user_session &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;UserSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;slice&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:email&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:password&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:errors&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;unauthorized&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; user_session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; user_session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user

      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:session&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; user_session&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s how it can be implemented easily. Note that we are using &lt;code class=&quot;language-text&quot;&gt;authlogic&lt;/code&gt; as our authentication system. If you are using something else, only the &lt;code class=&quot;language-text&quot;&gt;resolve&lt;/code&gt; implementation would change.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unit Testing Hooks containing GraphQL Queries]]></title><link>https://pulkitgoyal.in/testing-graphql-hooks</link><guid isPermaLink="false">https://pulkitgoyal.in/testing-graphql-hooks</guid><pubDate>Sun, 20 Sep 2020 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you jumped on the &lt;code class=&quot;language-text&quot;&gt;hooks&lt;/code&gt; train on react, you would know that it is exciting. But React officially doesn’t (yet)  have a way to test hooks. Yes, you could set up a dummy component that renders the hook and test it out. But soon, you want to do some advance handling inside the hook that the dummy component doesn’t allow testing for. &lt;/p&gt;
&lt;h2&gt;Testing Hooks&lt;/h2&gt;
&lt;p&gt;Before we jump on to testing hooks containing GraphQL queries, let’s get this out of the way. What if you want to test just a simple hook and you are seeing the following error:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Invariant Violation: Hooks can only be called inside the body of a function component.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;a href=&quot;https://github.com/testing-library/react-hooks-testing-library&quot;&gt;react-hooks-testing-library&lt;/a&gt; provides a &lt;code class=&quot;language-text&quot;&gt;renderHook&lt;/code&gt; method that allows to render the hook in a stand alone component for testing. The usage is very simple, just return the results of the hook from the callback of &lt;code class=&quot;language-text&quot;&gt;renderHook&lt;/code&gt;. The current return value of the hook will be present in &lt;code class=&quot;language-text&quot;&gt;result.current&lt;/code&gt;. So if your hook returns a number (count) and a method (increment) to update that count, you could write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;should increment counter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderHook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;act&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Hooks with GraphQL Queries&lt;/h2&gt;
&lt;p&gt;So we know it is simple to test regular hooks. What if there’s a hook that contains some &lt;code class=&quot;language-text&quot;&gt;useQuery&lt;/code&gt; statements, or uses &lt;code class=&quot;language-text&quot;&gt;client.query&lt;/code&gt; from an &lt;code class=&quot;language-text&quot;&gt;effect&lt;/code&gt;. Something along the lines of: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useModelWithNestedFetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useApolloClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;queryState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; variables&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; skip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setModel&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;newModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;id &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;newModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; nestedIds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;model&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;nestedIds&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;nestedIds&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;?.&lt;/span&gt;model &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; nesteds&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Load nesteds&lt;/span&gt;
    client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; gqlDynamic&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
        query Nesteds {
          &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;nestedIds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
          nested_&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;id&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;: nested(id:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;id&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;) {
            ...NestedInfo
          }
          &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;\n&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
        }
      &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;nestedData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; nesteds&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nestedData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;failed to fetch nesteds&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setModel&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;queryState &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I know this is a lot of code, but we never said we were testing a simple hook, did we. Let’s first see what it is doing. We are first fetching (or initializing if it is a new record) a model. The API, unfortunately, doesn’t embed the nested records and returns only &lt;code class=&quot;language-text&quot;&gt;nestedIds&lt;/code&gt; inside the field. So after fetching the record, we run another query that is generated at runtime to fetch each of the nested records and then use &lt;code class=&quot;language-text&quot;&gt;setModel&lt;/code&gt; callback to update or fetched model with the loaded nested records. &lt;/p&gt;
&lt;p&gt;Now comes the interesting part, how do we test this?&lt;/p&gt;
&lt;p&gt;The first thing that we need to do is mock out the queries. But it is difficult to do that inside a hook. So what we will do instead is mock out those hooks themselves. It is easy with &lt;code class=&quot;language-text&quot;&gt;jest.mock&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@apollo/react-hooks&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; nested1 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;../../../fixtures/nesteds&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; model1 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;../../../fixtures/models&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    model&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; model1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; fetchMore &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; nested1 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    __esModule&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    useMutation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    useQuery&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fetchMore &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    useApolloClient&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, time for our first test, where we will just test that the new model is initialized properly&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;doesn\&apos;t query and returns new model when id new&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderHook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useModelWithNestedFetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;new&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;QUERY&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;newModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;useQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;calls&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;skip&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeTruthy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The second test will validate that we query for our model and then after an effect, we also query for the nested records. Here we will use the &lt;code class=&quot;language-text&quot;&gt;waitForNextUpdate&lt;/code&gt; from the testing library’s &lt;code class=&quot;language-text&quot;&gt;renderHook&lt;/code&gt; return value to wait for the effect to update the state. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;queries for model&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; waitForNextUpdate &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderHook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useModelWithNestedFetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;QUERY&apos;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;model1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;useQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;calls&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;skip&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeFalsy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;useQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;calls&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;variables&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;useApolloClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;results&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toHaveBeenCalledTimes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;act&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;advanceTimersByTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;waitForNextUpdate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nesteds&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;nested1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are following along, you might be wondering why your tests are intermittently failing, right? That is because, we are missing a very important part of the setup. You remember we returned a promise from the Apollo &lt;code class=&quot;language-text&quot;&gt;client.query&lt;/code&gt; mock? That promise would sometimes resolve before the next statement and sometimes not. We need to use fake timers to make sure the promises/timeouts are properly handled:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useFakeTimers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    useMutation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    useQuery&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    useApolloClient&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;mock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; mock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mockClear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Using Action Mailbox on Rails 6]]></title><link>https://pulkitgoyal.in/using-action-mailbox-on-rails</link><guid isPermaLink="false">https://pulkitgoyal.in/using-action-mailbox-on-rails</guid><pubDate>Wed, 08 Jul 2020 18:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Action Mailbox is a framework available with Rails 6 to handle incoming emails with Rails. It integrates with a variety of service providers out of the box including SendGrid, Mandrill, Mailgun, or self hosted Exim, Postfix or Qmail. It stores all emails in the database and also provides declarative routing for mails to custom &lt;code class=&quot;language-text&quot;&gt;Mailbox&lt;/code&gt;es. A great usecase we have for this feature is to allow imports (or file uploads, for example) to certain users directly through email.&lt;/p&gt;
&lt;p&gt;The first step is to install &lt;code class=&quot;language-text&quot;&gt;action_mailbox&lt;/code&gt; to the application. Run &lt;code class=&quot;language-text&quot;&gt;rails action_mailbox:install&lt;/code&gt;. If everything went well, this will create some new migrations and a file &lt;code class=&quot;language-text&quot;&gt;app/mailboxes/application_mailbox.rb&lt;/code&gt;. Run the migrations to create the required tables on your DB.&lt;/p&gt;
&lt;h2&gt;Routing Emails&lt;/h2&gt;
&lt;p&gt;The routes for the emails are defined in &lt;code class=&quot;language-text&quot;&gt;application_mailbox&lt;/code&gt;. The rules are processed from top to bottom and the mail is delivered to the first matched mailbox. Here’s a sample route definition that forwards all emails coming to &lt;code class=&quot;language-text&quot;&gt;import-{key}@example.com&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;ImportMailbox&lt;/code&gt; and all others to a &lt;code class=&quot;language-text&quot;&gt;BounceMailbox&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ApplicationMailbox&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActionMailbox&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Base&lt;/span&gt;
  routing&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;import&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;\w&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;@&lt;span class=&quot;token comment&quot;&gt;#{ENV.fetch(&quot;INBOUND_EMAIL_DOMAIN&quot;, &quot;example.com&quot;)}\Z/i =&gt; :import)&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;# bounce all other emails&lt;/span&gt;
  routing&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:all&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:bounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Create mailboxes&lt;/h2&gt;
&lt;p&gt;To handle our incoming emails, we will need to create custom mailboxes. We can have Rails generate them for us using &lt;code class=&quot;language-text&quot;&gt;rails g mailbox &amp;lt;&amp;lt;name&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;From our routing through &lt;code class=&quot;language-text&quot;&gt;ApplicationMailbox&lt;/code&gt;, the emails coming with &lt;code class=&quot;language-text&quot;&gt;import-xyz@example.com&lt;/code&gt; will automatically call &lt;code class=&quot;language-text&quot;&gt;ImportMailbox#process&lt;/code&gt;. We can then access &lt;code class=&quot;language-text&quot;&gt;mail&lt;/code&gt; details using:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;mail.from&lt;/code&gt; - Array&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;mail.recipients&lt;/code&gt; - Array&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;mail.subject&lt;/code&gt; - String&lt;/li&gt;
&lt;li&gt;See &lt;code class=&quot;language-text&quot;&gt;body&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;attachments&lt;/code&gt; methods below for other details&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImportMailbox&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ApplicationMailbox&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;process&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;# Handle mail here&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;body&lt;/span&gt;&lt;/span&gt;
    mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decoded
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;attachments&lt;/span&gt;&lt;/span&gt;
    mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attachments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;map &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;attachment&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# access attachment.fiilename, attachment.decoded, attachment.content_type&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;# You can also add the attachments to a model (e.g. `Resource` here)  connected to ActiveStorage&lt;/span&gt;
      &lt;span class=&quot;token constant&quot;&gt;Resource&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:name&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; attachment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filename&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tap &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;r&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
        r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attachment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attach&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:io&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;StringIO&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;attachment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decoded&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                            &lt;span class=&quot;token symbol&quot;&gt;:filename&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; attachment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;filename&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                            &lt;span class=&quot;token symbol&quot;&gt;:content_type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; attachment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content_type&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        r&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;save&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you need to bounce emails (for example, if they don’t match any user’s address), you can use &lt;code class=&quot;language-text&quot;&gt;bounce_with&lt;/code&gt; with reference to an email (can be generated using &lt;code class=&quot;language-text&quot;&gt;ActionMailer&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;bounce_with &lt;span class=&quot;token constant&quot;&gt;BounceMailer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;invalid_to_address&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;first&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Unit testing mailboxes&lt;/h2&gt;
&lt;p&gt;The official &lt;code class=&quot;language-text&quot;&gt;ActionMailbox&lt;/code&gt; docs are very light about the topic of unit testing mailboxes. &lt;a href=&quot;https://github.com/rails/rails/blob/master/actionmailbox/lib/action_mailbox/test_helper.rb&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ActionMailbox::TestHelper&lt;/code&gt;&lt;/a&gt; provides some utility methods to test emails. The core methods of importance are &lt;code class=&quot;language-text&quot;&gt;receive_inbound_email_from_fixture&lt;/code&gt; (which reads from an &lt;code class=&quot;language-text&quot;&gt;eml&lt;/code&gt; file fixture) and &lt;code class=&quot;language-text&quot;&gt;receive_inbound_email_from_mail&lt;/code&gt; which accepts a block to configure the email.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;receive_inbound_email_from_mail &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;mail&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
  mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to &lt;span class=&quot;token string&quot;&gt;&quot;To Name &amp;lt;to@example.com&gt;&quot;&lt;/span&gt;
  mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;from &lt;span class=&quot;token string&quot;&gt;&quot;From Name &amp;lt;from@bagend.com&gt;&quot;&lt;/span&gt;
  mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;subject &lt;span class=&quot;token string&quot;&gt;&quot;Test subject&quot;&lt;/span&gt;
  mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text_part &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;part&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    part&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token string&quot;&gt;&quot;test body&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;html_part &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;part&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    part&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;h1&gt;test body&amp;lt;/h1&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The core of the testing depends on the ruby &lt;a href=&quot;https://github.com/mikel/mail&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;mail&lt;/code&gt;&lt;/a&gt; library. So if you find that the test helper isn’t working for you or has some limitations (for example, I couldn’t get it to work with attachments), you can always fall back to the &lt;code class=&quot;language-text&quot;&gt;Mail&lt;/code&gt; implementation. Here is my sample implementation:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rb&quot;&gt;&lt;pre class=&quot;language-rb&quot;&gt;&lt;code class=&quot;language-rb&quot;&gt;mail &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Mail&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
  from    &lt;span class=&quot;token string&quot;&gt;&quot;from@example.com&quot;&lt;/span&gt;
  to      &lt;span class=&quot;token string&quot;&gt;&quot;to@example.com&quot;&lt;/span&gt;
  cc      &lt;span class=&quot;token string&quot;&gt;&quot;cc@example.com&quot;&lt;/span&gt;
  subject &lt;span class=&quot;token string&quot;&gt;&quot;Test subject&quot;&lt;/span&gt;
  content_type  &lt;span class=&quot;token string&quot;&gt;&quot;multipart/mixed&quot;&lt;/span&gt;
  part&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:content_type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;multipart/alternative&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;part &lt;span class=&quot;token string&quot;&gt;&quot;text/html&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
      p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test body&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;part &lt;span class=&quot;token string&quot;&gt;&quot;text/plain&quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;p&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
      p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test body&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attachments&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment.csv&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:mime_type&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;text/csv&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:content&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;a,b,c&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
inbound &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActionMailbox&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;InboundEmail&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;create_and_extract_message_id&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:status&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:processing&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

inbound&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;route&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Send notifications with Firebase from Firestore events using Cloud Functions]]></title><link>https://pulkitgoyal.in/send-notifications-with-firebase-from-firestore-events-using-cloud-functions</link><guid isPermaLink="false">https://pulkitgoyal.in/send-notifications-with-firebase-from-firestore-events-using-cloud-functions</guid><pubDate>Sat, 20 Jun 2020 09:57:00 GMT</pubDate><content:encoded>&lt;p&gt;Firebase is great for quick MVPs when you don’t want to invest too much time on the server side. Let’s look at one of the most powerful Firebase features, Cloud Functions. With this, you can write any code that will be executed on Firebase’s servers to create custom web hooks or to respond to changes in the database.&lt;/p&gt;
&lt;h2&gt;Firestore Schema&lt;/h2&gt;
&lt;p&gt;Let’s take example of a chat app and see how we can send notifications to users on new incoming messages with these functions. It depends heavily on the database schema, so let’s quickly go over the schema we will be handling with &lt;code class=&quot;language-text&quot;&gt;Firestore&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/cf14147c7a894e52d1a3fc40e23c0004/5a190/db_shtx0d.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 800px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 70.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAOCAIAAACgpqunAAAACXBIWXMAABYlAAAWJQFJUiTwAAACiElEQVQoz21RW08TQRjdP+KbL0Z99UVflBeN8cEElYAJCSLxReMFTNAgikLVCKQCBhViBRRoK7fENF7AYLhpxISIEKpISttt9z67szt7b/12V/BBT04m38x8Z/LNOVRv4kt4ZK791WzLy+nQoM+h6Vt9U8/ffl36ST+IzXSOLzwcmw+PzkPRMbbwaOJTW3z2RmRyYm6VKmuOHr85WHI1squqY0915+7qzr01XTsrwxWh+OjM90N1kbLm2Ik70dKm4dKmoZO3h8tbYiV1kR3lbfW976hNml1Zz2zmhXRe8FZG3MgwKz9S6TyPib6cTC0uJxe/rSVT9HqGDZjcyEIDJ8qUoRNVRkTFpqHbpgE0CFGQpGuaY9saVmRJVLFimbpjmUDXtnQNFKJlmhTGajZL5/J5KIgPjDHP87Dati0IAk3TcKXrenALBUKIYRgoKAVjlmWzNM3xvEaIpmmKosCJLMsgLhTcYrHguq7j2NsseFsYy6YcGINoRFNh7KLrAF3Hsgwdzm3bUYkhq0SBmQxT3yLUpmV54tb4bENksmngQ2Pf1OXuBPDK48SFrtf3hj6uppjK+yNn28fPhSeONbw4XN9/5Fr/0esDB2ufJT6vFYtFqrpt7PTdOKzlodj+i0+BBy717Dv/5FRzNJnmarsT9T1vGiPva9rHq1pHz3gcqQhFp5d+eWJeROkcy0kKKyBJxkhRBQll6BwniPA1SZJUFdwy4FMBEZKQJFqW6Y0NH1ZkpPlRGT5VjCUR4sHgChjLsgzHsmA+8Q0XfZimL4aHcz6CGAAQD+t3gxg8h1Q4joO2ICqY5a8YOlwf9haCk6AGMeQMz23nLPj4Iw6aLN/6f2H9D6aXlNf/G1PMxsFbnhKHAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Firestore DB Schema&quot;
        title=&quot;&quot;
        src=&quot;/static/cf14147c7a894e52d1a3fc40e23c0004/5a190/db_shtx0d.png&quot;
        srcset=&quot;/static/cf14147c7a894e52d1a3fc40e23c0004/8ff5a/db_shtx0d.png 240w,
/static/cf14147c7a894e52d1a3fc40e23c0004/e85cb/db_shtx0d.png 480w,
/static/cf14147c7a894e52d1a3fc40e23c0004/5a190/db_shtx0d.png 800w&quot;
        sizes=&quot;(max-width: 800px) 100vw, 800px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So whenever a new message is sent, we create a new &lt;code class=&quot;language-text&quot;&gt;Thread&lt;/code&gt; and add it to the active channel.&lt;/p&gt;
&lt;h2&gt;Function&lt;/h2&gt;
&lt;p&gt;The first step is to set up your project for development. &lt;a href=&quot;https://firebase.google.com/docs/functions/local-emulator&quot;&gt;Firebase has a good guide on it&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We will use the &lt;code class=&quot;language-text&quot;&gt;onCreate&lt;/code&gt; function on firestore document to be notified whenever a new record is created in a collection.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;exports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendChatNotifications &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; functions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firestore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channels/{cid}/thread/{did}&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;threadSnapshot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next step is to find all the participants of the channel this message was sent to.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; participants &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; admin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;firestore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channel_participation&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;==&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After we find the participants, we will use &lt;code class=&quot;language-text&quot;&gt;sendToDevice&lt;/code&gt; method on the admin messaging API to actually send out the notification. Don’t forget the &lt;code class=&quot;language-text&quot;&gt;sound&lt;/code&gt; key to make sure the notification makes a sound on all devices. We can also include custom &lt;code class=&quot;language-text&quot;&gt;image&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;icon&lt;/code&gt; in the notification by passing urls to images. Here is the full code with everything put together.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; functions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;firebase-functions&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; admin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;firebase-admin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

admin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;initializeApp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  credential&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; admin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;credential&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;applicationDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  databaseURL&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;...&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

exports&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;sendChatNotifications &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; functions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firestore&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channels/{cid}/thread/{did}&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;threadSnapshot&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; thread &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; threadSnapshot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; senderId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; thread&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;senderID&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Finding channel participants with channel &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cid&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; participants &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; admin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;firestore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channel_participation&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;channel&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;==&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;params&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;participants&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;empty&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;There are no participants to send to.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  participants&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;snapshot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; uid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; snapshot&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;uid &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; senderId&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; user &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; admin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;firestore&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;users/&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;uid&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; payload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      notification&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        title&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; thread&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;senderFirstName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; thread&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        icon&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; thread&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;senderProfilePictureURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        image&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; thread&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        sound&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;default&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; admin&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;messaging&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sendToDevice&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fcmToken&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; payload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All we need now is to deploy this function. We can do that with &lt;code class=&quot;language-text&quot;&gt;yarn firebase deploy --only=functions&lt;/code&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Unit Test custom React Hooks that rely on Promise]]></title><link>https://pulkitgoyal.in/unit-test-custom-react-hooks-that-rely-on-promise-3</link><guid isPermaLink="false">https://pulkitgoyal.in/unit-test-custom-react-hooks-that-rely-on-promise-3</guid><pubDate>Sat, 06 Jun 2020 09:57:00 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/0f5efa9667c53d4ad28a1d9671cb7b9a/bd930/hook_kozmyn.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 42.083333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAIABQDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQC/8QAFQEBAQAAAAAAAAAAAAAAAAAAAgP/2gAMAwEAAhADEAAAAZck6Shj/8QAFxABAQEBAAAAAAAAAAAAAAAAAQACEf/aAAgBAQABBQJS0zt7/8QAFxEBAAMAAAAAAAAAAAAAAAAAAAECEf/aAAgBAwEBPwGzZf/EABcRAQADAAAAAAAAAAAAAAAAAAABAhH/2gAIAQIBAT8BqyH/xAAWEAEBAQAAAAAAAAAAAAAAAAAAITH/2gAIAQEABj8CqYj/xAAaEAACAwEBAAAAAAAAAAAAAAABEQAhUTFB/9oACAEBAAE/IUlzCFkjpilGRoD5k//aAAwDAQACAAMAAAAQd9//xAAXEQADAQAAAAAAAAAAAAAAAAAAARFB/9oACAEDAQE/EHrIaf/EABcRAAMBAAAAAAAAAAAAAAAAAAABEWH/2gAIAQIBAT8QSIwP/8QAGxAAAgMAAwAAAAAAAAAAAAAAAREAITFhgZH/2gAIAQEAAT8QMMiLKa6gVYMHbMFaNVVxKInMP4n/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;hook kozmyn&quot;
        title=&quot;&quot;
        src=&quot;/static/0f5efa9667c53d4ad28a1d9671cb7b9a/6a068/hook_kozmyn.jpg&quot;
        srcset=&quot;/static/0f5efa9667c53d4ad28a1d9671cb7b9a/09b79/hook_kozmyn.jpg 240w,
/static/0f5efa9667c53d4ad28a1d9671cb7b9a/7cc5e/hook_kozmyn.jpg 480w,
/static/0f5efa9667c53d4ad28a1d9671cb7b9a/6a068/hook_kozmyn.jpg 960w,
/static/0f5efa9667c53d4ad28a1d9671cb7b9a/644c5/hook_kozmyn.jpg 1440w,
/static/0f5efa9667c53d4ad28a1d9671cb7b9a/0f98f/hook_kozmyn.jpg 1920w,
/static/0f5efa9667c53d4ad28a1d9671cb7b9a/bd930/hook_kozmyn.jpg 4016w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So you wrote a fancy custom hook that fetches some information from an API. How do we unit test such hooks?&lt;/p&gt;
&lt;h2&gt;Simple Hooks&lt;/h2&gt;
&lt;p&gt;Before we get to testing async hooks, you should already know how to test hooks. There are already some posts about it elsewhere (&lt;a href=&quot;https://medium.com/@nitinpatel_20236/unit-testing-custom-react-hooks-caa86f58510&quot;&gt;this one&lt;/a&gt; is an excellent example), so I will not repeat all that was already said there. We will use the &lt;a href=&quot;https://github.com/testing-library/react-hooks-testing-library&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;react-hooks-testing-library&lt;/code&gt;&lt;/a&gt; for this purpose. Here’s an example from the library:&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;useCounter.js&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useState&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useCallback &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;react&apos;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCount&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; increment &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; increment &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; useCounter&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;useCounter.test.js&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; renderHook&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; act &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;@testing-library/react-hooks&apos;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; useCounter &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;./useCounter&apos;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;should increment counter&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderHook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;act&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Testing async hooks&lt;/h2&gt;
&lt;p&gt;Assume that instead of a local counter, we are fetching the count from a GraphQL API using Apollo Client’s &lt;code class=&quot;language-text&quot;&gt;query&lt;/code&gt; method. I know we could use Apollo’s react hook directly, but this is a contrived example as the async part could be anything.&lt;/p&gt;
&lt;h3&gt;&lt;code class=&quot;language-text&quot;&gt;useCounter.js&lt;/code&gt;&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useQuery&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useApolloClient &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;@apollo/react-hooks&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; gql &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;graphql.macro&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useEffect &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;QUERY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gql&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;query Counter($id:ID!) { counter(id: $id) { count } }&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setCount&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useApolloClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    client&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;QUERY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      variables&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;counter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;failed to fetch count&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;client&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to test this hook, we need a way to have a mocked result being passed to the query. First, we need to mock out the client and its query function. You need to change it to mock out your actual calls. I will mock out the query with a promise that resolves to some data after 100ms.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mock&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;@apollo/react-hooks&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; client &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    query&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resolve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; counter&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    __esModule&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    useApolloClient&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; client&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We created a promise that resolves after 100 ms. Now, we could wait for 100ms in our tests and then check the result after that time. But that doesn’t really work when we have a lot of tests or the promise could resolve before we get to the next statement if something takes time on the test framework. We will instead use fake timers. We will do this is a &lt;code class=&quot;language-text&quot;&gt;beforeEach&lt;/code&gt; to execute before each test in the file.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;beforeEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useFakeTimers&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  useApolloClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mockClear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now to the actual test which is actually pretty self-explanatory.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;it&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;fetches and resolves to a count&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; waitForNextUpdate &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;renderHook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCounter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toBeFalsy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;useApolloClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;mock&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;results&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;act&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; jest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;advanceTimersByTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;waitForNextUpdate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toEqual&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Transform SVG icons and images to React Components]]></title><link>https://pulkitgoyal.in/transform-svg-icons-and-images-to-react-component</link><guid isPermaLink="false">https://pulkitgoyal.in/transform-svg-icons-and-images-to-react-component</guid><pubDate>Tue, 12 May 2020 09:57:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;There are plenty of ways to include SVG files in your React apps. One that I was using until recently was to include the SVG with an &lt;code class=&quot;language-text&quot;&gt;object&lt;/code&gt; tag. While it worked ok, there’s a much better way. What if you could include the SVG files directly in the generated markup?&lt;/p&gt;
&lt;h2&gt;Enter SVGR&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/gregberge/svgr&quot;&gt;SVGR&lt;/a&gt; provides a way to generate react components from SVG files that you can easily import in your code. It comes built-in with &lt;code class=&quot;language-text&quot;&gt;create-react-app&lt;/code&gt;, so if your code is generated from it, you don’t need to read further. In fact, the &lt;a href=&quot;https://react-svgr.com/&quot;&gt;official docs&lt;/a&gt; cover the default behavior pretty well and it is easy to set up.&lt;/p&gt;
&lt;p&gt;But if you are looking for a solution to generate &lt;code class=&quot;language-text&quot;&gt;tsx&lt;/code&gt; files from SVG, you are in the right place. From the documentation, &lt;code class=&quot;language-text&quot;&gt;svgr&lt;/code&gt; has an &lt;a href=&quot;https://react-svgr.com/docs/custom-templates/&quot;&gt;option to specify a template&lt;/a&gt; that you want it to use.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A custom template takes place in a file that exports a “template function”.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;This function is called in a babel plugin: babel-plugin-transform-svg-component and must returns a Babel AST. If you are not familiar with all Babel stuff, you should read &lt;a href=&quot;https://github.com/jamiebuilds/babel-handbook&quot;&gt;this guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Reading the Babel AST guide, we can prepare our template so that it writes out a typescript file instead of vanilla JS.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;function defaultTemplate(
  { template },
  opts,
  { imports, interfaces, componentName, props, jsx, exports },
) {
  const plugins = [&amp;#39;jsx&amp;#39;]
  if (opts.typescript) {
    plugins.push(&amp;#39;typescript&amp;#39;)
  }
  const typeScriptTpl = template.smart({ plugins })
  return typeScriptTpl.ast`${imports}
${interfaces}
function ${componentName}(${props}) {
  return ${jsx};
}
${exports}
  `
}
module.exports = defaultTemplate&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now use this template when processing the SVG files:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;$ yarn svgr --template template.js play.svg&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s the output of &lt;code class=&quot;language-text&quot;&gt;play.tsx&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;SvgPlay&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;svg baseProfile&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;tiny&quot;&lt;/span&gt; viewBox&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;0 0 24 34&quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;path d&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;M7 22.2V11.8c0-.8.9-1.2 1.5-.8l8.1 5.2c.6.4.6 1.3 0 1.7L8.5 23c-.6.4-1.5 0-1.5-.8z&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;svg&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; SvgPlay&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Automation&lt;/h2&gt;
&lt;p&gt;If you are looking to automate the generation of these files so that you don’t have to run these commands every time a new SVG file is added, here’s how you can do that with Grunt (it’s possible with many other tools, including &lt;code class=&quot;language-text&quot;&gt;gulp&lt;/code&gt;, but our project was using Grunt).&lt;/p&gt;
&lt;p&gt;We need to use the &lt;a href=&quot;https://github.com/sindresorhus/grunt-shell&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;grunt-shell&lt;/code&gt;&lt;/a&gt; task with this config.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;svgr: {
  command: &amp;#39;yarn svgr --ext tsx --template lib/misc/svgr_template.js -d lib/src/svg lib/svg&amp;#39;,
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Apollo Client Default Values for Missing Fields]]></title><link>https://pulkitgoyal.in/apollo-client-default-missing-fields</link><guid isPermaLink="false">https://pulkitgoyal.in/apollo-client-default-missing-fields</guid><pubDate>Mon, 13 Apr 2020 04:58:27 GMT</pubDate><content:encoded>&lt;p&gt;GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.&lt;/p&gt;
&lt;p&gt;But what if you want to ask for incremental data updates (e.g. as part of a subscription). There is no way in GraphQL to listen for incremental data from a subscription. Of course, you can ask for all data and then the server could be coded to transmit incremental updates. But this doesn’t work on the client-side if you are using Apollo Client because it expects all data that you have queried for in your subscription.&lt;/p&gt;
&lt;p&gt;There are some libraries on the that try to provide a way to remove duplicates from GraphQL responses, e.g. &lt;a href=&quot;https://github.com/gajus/graphql-deduplicator&quot;&gt;graphql-deduplicator&lt;/a&gt; but it doesn’t have support for merging missing fields.&lt;/p&gt;
&lt;p&gt;Here is a quick implementation that defaults all missing fields to a null value. You can then use your own implementation to merge the values as you see fit, but this gets rid of the Apollo Client errors of the kind &lt;code class=&quot;language-text&quot;&gt;Missing field X&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The first step is to add a method to your &lt;code class=&quot;language-text&quot;&gt;Model&lt;/code&gt; (it assumes that all your models inherit from a base &lt;code class=&quot;language-text&quot;&gt;Model&lt;/code&gt;) objects that you want to handle.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Converts missing fields to nulls to play well with Apollo client&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fillUndefineds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;clazz&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; Model&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; object&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;object&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; meta &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; clazz&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;meta&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attributes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; clazz &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;undefined&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        object&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;object&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; clazz&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        object&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillUndefineds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;clazz&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next step is to mark some meta attributes on the models you are trying to convert. You can create your own format for the meta, but here is something that I have used in the past.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Movie&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
Movie&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  attributes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;name&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;TYPE_STRING&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Event&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Model&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
Event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meta &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  attributes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    movie&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;movie&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; clazz&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Movie &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we can create a custom &lt;code class=&quot;language-text&quot;&gt;SubscriptionClient&lt;/code&gt; and set it on our &lt;code class=&quot;language-text&quot;&gt;Link&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// To automatically convert missing backend values to null, use this client&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// This doesn&apos;t suit well for partial objects (which contain only the changed data)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// but can be used if the app is sure that it will receive a full object.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WSSubscriptionClient&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SubscriptionClient&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observable&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; parentObservable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;req&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; observable &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;observer&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Observer&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; parentObservable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function-variable function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; event &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Model&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fillUndefineds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Event&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;event&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; data&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; event &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function-variable function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;err&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;err&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token function-variable function&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;complete &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;complete&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; observable&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; subscriptionClient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WSSubscriptionClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; reconnect&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wsLink &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WebSocketLink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;subscriptionClient&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; apolloClient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ApolloClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; link&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; wsLink&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cache&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;InMemoryCache&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Advanced Mixins on Typescript]]></title><link>https://pulkitgoyal.in/advanced-mixins-on-typescript</link><guid isPermaLink="false">https://pulkitgoyal.in/advanced-mixins-on-typescript</guid><pubDate>Thu, 28 Mar 2019 15:01:34 GMT</pubDate><content:encoded>&lt;h2&gt;Mixins on Typescript&lt;/h2&gt;
&lt;p&gt;TypeScript 2.2 first introduced the support for mixins to huge applause from the developers. Mixins pattern allows you to abstract code into separate chunks and DRY code is always better, right? A very simple example of a mixin from the official TypeScript docs:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;typescript&quot;&gt;&lt;pre class=&quot;language-typescript&quot;&gt;&lt;code class=&quot;language-typescript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Point&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Person&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;type&lt;/span&gt; Constructor&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; Tagged&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Constructor&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Base&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;extends&lt;/span&gt; Base &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        _tag&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_tag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; TaggedPoint &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Tagged&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Point&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; point &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;TaggedPoint&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
point&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_tag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;hello&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Tagged&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Person&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    accountBalance&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; customer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Customer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Joe&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
customer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;_tag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;test&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
customer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;accountBalance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;So in short, mixins can be used to supercharge your classes with extra attributes and methods. But what if you want to inject a common functionality to several similar classes that all implement a particular interface. For example, let’s say you have a mixin that produces some sound.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;// Activatable Mixin
class Speakable {
    speak() {
      // Speak something
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This can then be injected into a &lt;code class=&quot;language-text&quot;&gt;Dog&lt;/code&gt; and a &lt;code class=&quot;language-text&quot;&gt;Cat&lt;/code&gt; to make them speak. But what if the &lt;code class=&quot;language-text&quot;&gt;speak&lt;/code&gt; method needs to call a specific method &lt;code class=&quot;language-text&quot;&gt;sound&lt;/code&gt; on the instances? While this is possible with TypeScript, it is very hard to set up. Here is how an implementation for this would look like.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;interface Animal {
  sound: string;
  speak: () =&amp;gt; void;
}

type Constructor&amp;lt;T = Animal&amp;gt; = new (...args: any[]) =&amp;gt; T;

export default function Speakable&amp;lt;TBase extends Constructor&amp;gt;(Base: TBase) {
  return class extends Base {
    speak(this.sound);
  };
}

class BaseDog extends Animal {
  sound = &amp;#39;wow&amp;#39;;
  speak() { throw new Error(&amp;#39;Method not implemented.&amp;#39;); }
}

class Dog extends Speakable(BaseDog) {}

class BaseCat extends Animal {
  sound = &amp;#39;meow&amp;#39;;
  speak() { throw new Error(&amp;#39;Method not implemented&amp;#39;); }
}

class Cat extends Speakable(BaseCat) {}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s break this down. We have an interface &lt;code class=&quot;language-text&quot;&gt;Animal&lt;/code&gt; that is supposed to have a &lt;code class=&quot;language-text&quot;&gt;sound&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;speak&lt;/code&gt; something. But since the &lt;code class=&quot;language-text&quot;&gt;speak&lt;/code&gt; implementation is very involved and same for all &lt;code class=&quot;language-text&quot;&gt;Animal&lt;/code&gt;s, we want to provide an abstraction for it rather than having to define it on all sub-classes of &lt;code class=&quot;language-text&quot;&gt;Animal&lt;/code&gt;. On the contrived example, you would say let’s create a helper function that both classes can call. While that sounds ok for a small example like this, when it gets to the point of providing several functionalities that depend on one another, say &lt;code class=&quot;language-text&quot;&gt;speak&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;walk&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;run&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;cry&lt;/code&gt; etc. it becomes really difficult to manage it with helper functions.&lt;/p&gt;
&lt;p&gt;The mixins approach, on the other hand, helps us compose classes as we would while allowing us to provide default implementations for the common methods into a single mixin. We could have several different mixins that can be nested one after the other to provide different independent functionalities too.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;class Cat extends Taggable(Speakable(BaseCat)) {}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;While this does look slightly hard to read, the benefit in terms of DRYness far outweights the small issue of aesthetics.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Custom fetch implementation for responses compressed with MessagePack::RackMiddleware]]></title><link>https://pulkitgoyal.in/custom-fetch-implementation-for-responses-compressed-with-messagepack-rackmiddleware</link><guid isPermaLink="false">https://pulkitgoyal.in/custom-fetch-implementation-for-responses-compressed-with-messagepack-rackmiddleware</guid><pubDate>Fri, 28 Dec 2018 13:49:42 GMT</pubDate><content:encoded>&lt;p&gt;After the &lt;a href=&quot;https://pulkitgoyal.in/custom-rack-middleware-for-response-compression/&quot;&gt;previous post&lt;/a&gt;, I have received some messages on how to use the responses passed through the custom middleware. So if you are not one of the guys using that middleware, this post is not for you. If you are, you’re in luck, keep reading.&lt;/p&gt;
&lt;p&gt;The easiest approach, if you don’t have a lot of requests going to the compressed API, as some have suggested is to manually add the header to the request and uncompress it when you receive a response. But this can soon get tiring for multiple requests and needs a better way to handle this, especially since it’s so easy.&lt;/p&gt;
&lt;p&gt;We can create a custom fetch that makes sure that this custom header is included in the request and parse the response if it is compressed. It has the same API as the native &lt;code class=&quot;language-text&quot;&gt;fetch&lt;/code&gt;, so it’s easy to get used to.&lt;/p&gt;
&lt;p&gt;Depending on what browsers you target, you might not need &lt;code class=&quot;language-text&quot;&gt;bluebird&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;request-promise&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;whatwg-fetch&lt;/code&gt;. This is from a code from a nodejs app which does require the latter two.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ts&quot;&gt;&lt;pre class=&quot;language-ts&quot;&gt;&lt;code class=&quot;language-ts&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;whatwg-fetch&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;bluebird&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; _ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;lodash&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; msgpack &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;msgpack-lite&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; request &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;request-promise&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nativeFetchJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetchJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; compressionEnabled &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;compressionEnabled&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;delete&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;compressionEnabled&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;compressionEnabled&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;nativeFetchJson&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; request&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    _&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultsDeep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      headers&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;x-messagepack-compression&apos;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      resolveWithFullResponse&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      encoding&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;then&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;headers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;x-messagepack-compression&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;true&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; msgpack&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;declare&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Promise&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;any&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Comment below if you want me to do a version without all of the dependencies and I’ll give it a shot.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Custom Rack Middleware for response compression]]></title><link>https://pulkitgoyal.in/custom-rack-middleware-for-response-compression</link><guid isPermaLink="false">https://pulkitgoyal.in/custom-rack-middleware-for-response-compression</guid><pubDate>Tue, 27 Nov 2018 18:23:00 GMT</pubDate><content:encoded>&lt;p&gt;If you are serving a Rails application, you are probably already using some sort of compression for the responses. If not, enabling simple gzip compression is pretty straightforward (using a simple middleware) and can give boosts of as much as 80% in some cases. You can put this in an initializer somewhere and your responses will be gzipped if the receiver supports it.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;middleware&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;insert_after &lt;span class=&quot;token constant&quot;&gt;ActionDispatch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Static&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Rack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Deflater&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The middleware automatically detects when compression is supported and allowed. For example, no transformation is made when a cache directive of ‘no-transform’ is present, or when the response status code is one that doesn’t allow an entity body.&lt;/p&gt;
&lt;p&gt;But, if you have a really specific use case, you can go one step further. For example, if you deal mostly in JSON responses, &lt;a href=&quot;https://msgpack.org/index.html&quot;&gt;messagepack&lt;/a&gt; could help your API get even leaner. A word of caution before you venture further, don’t expect huge savings if you are already using gzip compression as messagepack savings can vary hugely based on the kind of data you are transmitting over the socket.&lt;/p&gt;
&lt;p&gt;Let’s create a custom middleware that can compress responses with messagepack before sending them out. A few things that we need to keep in mind for this extension are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;It only compresses if there’s a specific header field (&lt;code class=&quot;language-text&quot;&gt;X-MessagePack-Compression&lt;/code&gt;) in the request signaling that it wants a compressed response.&lt;/li&gt;
&lt;li&gt;Since messagepack only works on JSON, make sure that it is executed only for JSON responses.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With these conditions, here’s a sample middleware that you can put in.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MessagePack&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;RackMiddleware&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;initialize&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;app&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token variable&quot;&gt;@app&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; app
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;@app&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;call&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; body&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;unless&lt;/span&gt; compress&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

      suppress&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt;
        body &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;MessagePack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pack&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Oj&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;load&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        headers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;X-MessagePack-Compression&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;compress&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;env&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; headers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      env&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;HTTP_X_MESSAGEPACK_COMPRESSION&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        headers&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Content-Type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;application/json;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Using the middleware is easy, you just need one extra line during initialization:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;Rails&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;application&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;middleware&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;use &lt;span class=&quot;token constant&quot;&gt;MessagePack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;RackMiddleware&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Implement Magic Login for TV devices]]></title><link>https://pulkitgoyal.in/implement-magic-login-for-tv-devices</link><guid isPermaLink="false">https://pulkitgoyal.in/implement-magic-login-for-tv-devices</guid><pubDate>Tue, 30 Oct 2018 11:04:49 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;I don’t know if that is the correct term for it, but it sure is magic to non-developers. I recently noticed this technique on the Youtube app on my TV. Here’s how it works: &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Begin the login process on Youtube app. It shows a unique 4 character code for the TV. &lt;/li&gt;
&lt;li&gt;Open Google app on your phone and navigate to the “authenticate other devices” page. &lt;/li&gt;
&lt;li&gt;It asks for a confirmation for the TV login on the mobile without entering anything and logs you in after the confirmation. &lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;How&lt;/h2&gt;
&lt;p&gt;So how does it work? It’s pretty simple, really. As soon as you open the authentication screen on the TV, it generates a unique code and starts playing an ultrasonic sound in a loop. The phone is capable of hearing this sound and identifying what code it is broadcasting. After that, it’s all a matter of communicating the right things over the API on the TV and the phone. &lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;Let’s see how we can do this. We will use the &lt;a href=&quot;https://chirp.io&quot;&gt;Chirp SDK&lt;/a&gt; for this purpose. The SDK will do all the heavy lifting of generating and identifying the tones, so all we need is to build a way for it. &lt;/p&gt;
&lt;h3&gt;TV App&lt;/h3&gt;
&lt;p&gt;Let’s start with the implementation on the TV. Since most of the devices use a different programming language, I wouldn’t dive into a language-specific guide. But for completeness, here’s a sample 4 liner in JS: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; audioContext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AudioContext &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;webkitAudioContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; connect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ChirpConnect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;APP_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; audioContext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; payload &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Uint8Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// TODO: Replace with your code&lt;/span&gt;
connect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;payload&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If your device isn’t compatible in generating the payload, fret not, because there’s an API that does that too. All you need is to download the file that &lt;code class=&quot;language-text&quot;&gt;https://audio.chirp.io/v3/ultrasonic/&amp;lt;&amp;lt;YOUR HEX ENCODED CODE&amp;gt;&amp;gt;&lt;/code&gt; generates and play it on a loop on your TV app. &lt;/p&gt;
&lt;h3&gt;Mobile App&lt;/h3&gt;
&lt;p&gt;The next step is to integrate it into your mobile app so you can detect these tones and perform your magic code for logging in the user. Again, setting up the SDK is as simple as it gets. Do this somewhere in &lt;code class=&quot;language-text&quot;&gt;viewWillAppear&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;connect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ChirpConnect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;appKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;APP_KEY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; andSecret&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;APP_SECRET&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; configError&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; connect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;YOUR&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;CONFIG&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STRING&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; startError&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; connect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

connect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;receivedBlock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channel&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UInt&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Received code &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; encoding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ascii&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// TODO: Initiate Login&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;receivedBlock&lt;/code&gt; will be executed with the data that it receives and you can initiate the login process from there. &lt;/p&gt;
&lt;p&gt;Of course, all of this needs to be aided with APIs on the backend to generate a unique code and then log the user in if requested from an authenticated end-point, but those are details that I will leave for you as the backend for most apps will very widely.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Ocean at the End of the Lane Review]]></title><link>https://pulkitgoyal.in/the-ocean-at-the-end-of-the-lane-review</link><guid isPermaLink="false">https://pulkitgoyal.in/the-ocean-at-the-end-of-the-lane-review</guid><pubDate>Tue, 02 Oct 2018 15:11:52 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/9b3b9e3e42ebd592ff6742e3dfd1a4df/2242b/15783514.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 311px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 152.91666666666666%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/jpeg;base64,/9j/2wBDABALDA4MChAODQ4SERATGCgaGBYWGDEjJR0oOjM9PDkzODdASFxOQERXRTc4UG1RV19iZ2hnPk1xeXBkeFxlZ2P/2wBDARESEhgVGC8aGi9jQjhCY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2NjY2P/wgARCAAfABQDASIAAhEBAxEB/8QAGAAAAwEBAAAAAAAAAAAAAAAAAAMEBQL/xAAWAQEBAQAAAAAAAAAAAAAAAAAAAQP/2gAMAwEAAhADEAAAAcN7qNMcwtFXRndLQSB//8QAGxAAAwACAwAAAAAAAAAAAAAAAAECAxESEyH/2gAIAQEAAQUC5EVunT3GFHVKHh9jKdsoeb3aOSG9n//EABgRAQEBAQEAAAAAAAAAAAAAAAEAEgIT/9oACAEDAQE/AXotF5lgv//EABcRAAMBAAAAAAAAAAAAAAAAAAABEBH/2gAIAQIBAT8BRl//xAAYEAADAQEAAAAAAAAAAAAAAAAAEDEhAf/aAAgBAQAGPwI5i0i0ihF//8QAGhAAAgMBAQAAAAAAAAAAAAAAAAERITFBcf/aAAgBAQABPyHwjBtwcd5eDy6FksLlcCUexkLwqF2DdwTJiD//2gAMAwEAAgADAAAAEPDXsv/EABcRAAMBAAAAAAAAAAAAAAAAAAABETH/2gAIAQMBAT8QywU8Gx0Rf//EABcRAQEBAQAAAAAAAAAAAAAAAAEAURH/2gAIAQIBAT8QLsrYUut//8QAHxABAAIBBQADAAAAAAAAAAAAAQARITFBUWFxgaHR/9oACAEBAAE/EBDahxUrQ1gyrPsJxVXKuowbvaiNiwNHL8xrGTNTRCPUQ36Q4lhm5MIFGCvca+wKnt71/fqDQGGa37n/2Q==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;15783514&quot;
        title=&quot;&quot;
        src=&quot;/static/9b3b9e3e42ebd592ff6742e3dfd1a4df/2242b/15783514.jpg&quot;
        srcset=&quot;/static/9b3b9e3e42ebd592ff6742e3dfd1a4df/09b79/15783514.jpg 240w,
/static/9b3b9e3e42ebd592ff6742e3dfd1a4df/2242b/15783514.jpg 311w&quot;
        sizes=&quot;(max-width: 311px) 100vw, 311px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Sussex, England. A middle-aged man returns to his childhood home to attend a funeral. Although the house he lived in is long gone, he is drawn to the farm at the end of the road, where, when he was seven, he encountered a most remarkable girl, Lettie Hempstock, and her mother and grandmother. He hasn’t thought of Lettie in decades, and yet as he sits by the pond (a pond that she’d claimed was an ocean) behind the ramshackle old farmhouse, the unremembered past comes flooding back. And it is a past too strange, too frightening, too dangerous to have happened to anyone, let alone a small boy.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As we age, we become our parents; live long enough and we see faces repeat in time.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If this is what childhood fantasy is like, I need more. Never knew this was a genre I could be interested in. A fantastic story, amazingly well written in first person voice.&lt;/p&gt;
&lt;p&gt;At about 156 pages, it’s a short read. But no way I would have expected to finish it as quickly as I did. It’s a real page turner and a very difficult book to put down. I won’t dive into the story as I usually do for other reviews because I don’t think I can give it justice. Just take dive in this Ocean and you won’t be disappointed.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;That’s the trouble with living things. Don’t last very long. Kittens one day, old cats the next. And then just memories. And the memories fade and blend and smudge together&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I am going to be sharing my progress on the books going forward. It shouldn’t be considered as an indication of the quality of the book as my reading habits might vary depending on my workload. But it is usually a good indication of how interestingly the book progresses.&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8b29e17c5f57f915d4da34c58d505760/0b533/ocean_progress_xklcwu.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 500px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 58.333333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAMCAIAAADtbgqsAAAACXBIWXMAABYlAAAWJQFJUiTwAAABK0lEQVQoz4VS7W7DIAzs+z/i1EpdmypfpQEM2ECS7Ui2Km2nDt0P6+zDZ/BumqZ5nr9ejohUVdW27Ta7xuM0jTkj2EmMwVNiH58gPicGtmROkmLQ7dkNfRHjMvbEXrM3TwiuoMRuje3luGdViVXjmLdi+wYSHNqy7mx9ZKfhNKf4j1jYhUASSF/r7vQRbQ8GPFz8iFNKuHjxadcEqjGwI21VK6bnoQm3GkNyKbMPYjz2ncVskKm+uTXnoGpTH8XeQJaCe81W/GsbDYvPoW9UtTfNZ4ThYpJeh3oUB8+ByA7BXF13Zqui8Jv3exA7o9j0w+VAXcXBBqRJL3+jF5hnkB7zImbm5nSITqfIEUf4jhSxErJlVhJfpfWArqXzX9tZDhFhSV95lGOpEXwDmgS0iPiAiYgAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;ocean progress xklcwu&quot;
        title=&quot;&quot;
        src=&quot;/static/8b29e17c5f57f915d4da34c58d505760/0b533/ocean_progress_xklcwu.png&quot;
        srcset=&quot;/static/8b29e17c5f57f915d4da34c58d505760/8ff5a/ocean_progress_xklcwu.png 240w,
/static/8b29e17c5f57f915d4da34c58d505760/e85cb/ocean_progress_xklcwu.png 480w,
/static/8b29e17c5f57f915d4da34c58d505760/0b533/ocean_progress_xklcwu.png 500w&quot;
        sizes=&quot;(max-width: 500px) 100vw, 500px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Use a custom job adapter in test]]></title><link>https://pulkitgoyal.in/use-a-custom-job-adapter-in-test</link><guid isPermaLink="false">https://pulkitgoyal.in/use-a-custom-job-adapter-in-test</guid><pubDate>Mon, 17 Sep 2018 14:05:48 GMT</pubDate><content:encoded>&lt;p&gt;So you have decided to jump on board the ship to scalability with the &lt;a href=&quot;https://pulkitgoyal.in/better-background-jobs-in-rails&quot;&gt;custom job adapter from the previous post&lt;/a&gt;? Want to use this adapter in your tests? Do you use &lt;a href=&quot;https://api.rubyonrails.org/v5.2/classes/ActiveJob/TestHelper.html#method-i-assert_enqueued_jobs&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;assert_enqueued_jobs&lt;/code&gt;&lt;/a&gt; in your tests? If yes, you wouldn’t see duplicate jobs being ignored from the queue. This is because it &lt;a href=&quot;https://github.com/rails/rails/blob/375a4143cf5caeb6159b338be824903edfd62836/activejob/lib/active_job/test_helper.rb#L37-L47&quot;&gt;automatically&lt;/a&gt; sets the adapter to &lt;code class=&quot;language-text&quot;&gt;test_adapter&lt;/code&gt; irrespective of what you have in your &lt;code class=&quot;language-text&quot;&gt;test.rb&lt;/code&gt;. Not all is lost though. There is a way to use your &lt;a href=&quot;https://github.com/rails/rails/blob/375a4143cf5caeb6159b338be824903edfd62836/activejob/lib/active_job/test_helper.rb#L64-L66&quot;&gt;custom adapter in tests&lt;/a&gt; by extending the ActiveJob::TestHelper.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Specifies the queue adapter to use with all active job test helpers.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Returns an instance of the queue adapter and defaults to&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# &amp;lt;tt&gt;ActiveJob::QueueAdapters::TestAdapter&amp;lt;/tt&gt;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# Note: The adapter provided by this method must provide some additional&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# methods from those expected of a standard &amp;lt;tt&gt;ActiveJob::QueueAdapter&amp;lt;/tt&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# in order to be used with the active job test helpers. Refer to&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# &amp;lt;tt&gt;ActiveJob::QueueAdapters::TestAdapter&amp;lt;/tt&gt;.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;queue_adapter_for_test&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token constant&quot;&gt;ActiveJob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;QueueAdapters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;TestAdapter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Great. All we need is this piece of code in our &lt;code class=&quot;language-text&quot;&gt;test_helper&lt;/code&gt; and we should be good:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;module ActiveJob::TestHelper
  def queue_adapter_for_test
    ActiveJob::QueueAdapters::UniqDelayedJobTestAdapter.new
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Not so fast, eh! Check out the docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: The adapter provided by this method must provide some additional methods from those expected of a standard &lt;tt&gt;ActiveJob::QueueAdapter&lt;/tt&gt; in order to be used with the active job test helpers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;OK. A little more digging, and we can extend our adapter to support the methods that the test adapter requires&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ActiveJob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;QueueAdapters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;UniqDelayedJobTestAdapter&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;ActiveJob&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;QueueAdapters&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;UniqDelayedJobAdapter&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;enqueued_jobs&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token constant&quot;&gt;Delayed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Job&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;all&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;to_a
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;performed_jobs&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Nice! Run the tests! Still failing… Looks like it expects the elements returned from &lt;code class=&quot;language-text&quot;&gt;enqueued_jobs&lt;/code&gt; to support a &lt;code class=&quot;language-text&quot;&gt;fetch&lt;/code&gt; method.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Delayed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Backend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Job&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; default &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; key
    &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:job&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;payload_object&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;job_data&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;job_class&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; default
    &lt;span class=&quot;token keyword&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:queue&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queue &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; default
    &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;cannot fetch &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;key&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;. Not yet implemented&quot;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, we can use the adapter in tests. Don’t forget to update your expected job counts to account for the duplicate ones discarded by the new adapter!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Rae]]></title><link>https://pulkitgoyal.in/rae</link><guid isPermaLink="false">https://pulkitgoyal.in/rae</guid><pubDate>Sat, 18 Aug 2018 06:02:48 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Why am I in a dark box?&lt;/em&gt; Lynn remembered being drunk. She and Rox were partying hard. Their play had gone so well. It was a great story too. A story of power, greed and corruption. A story of how Rae, The Dark Lord, rose to godhood with treachery and lies. Born in a time of anarchy, a time when killing had no meaning, life had no value, a time when there was no religion. Rae was the saviour, a messiah, but not every hero’s path is devoid of Blood. He brought order to the people, no matter how dire the ways. &lt;/p&gt;
&lt;p&gt;&lt;em&gt;What did I do yesterday? I knew we should have stopped after Rox got sick. Damn, we were driving fast. Oh no, we were in an accident. And… blood.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Rox had died on the spot. Lynn had seen her best friend bleed to her death before collapsing herself.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;I need to get out of here. They might have saved Rox.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;“Hello… Someone please help. Help me!”, Lynn shouting now. The box was dark and small and somehow had enough oxygen that she hadn’t run out of breath yet.&lt;/p&gt;
&lt;p&gt;“Hey, hey. Hold up. Praise Rae, you are finally up. ” A heavy voice from outside. Light started creeping in as the box gradually opened. Lynn instinctively closed her eyes from the blinding brightness. Everything went red with the light refracting through her eye lashes.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Where am I?&lt;/em&gt; She hadn’t seen a room this white before. White walls, white ceilings, white machines. Even the only other person in the room was wearing white.&lt;/p&gt;
&lt;p&gt;“Welcome back. You are in the Northwestern Medical center. You were put to sleep in 2018 after a car accident. We operated on you yesterday. By Rae’s mercy, you are as good as new now.” said the person, as if reading her mind.&lt;/p&gt;
&lt;p&gt;“You put me to sleep in 2018? What is that supposed to mean? What… year is this? ”&lt;/p&gt;
&lt;p&gt;“Don’t worry, it’s all right. We have been reviving the old people this week. You were put to cryogenic sleep because we didn’t have the technology then. And then… And then… Ah well, you will see soon enough. Someone will be with you soon to explain everything.”&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;The world had changed in the last century. There was apparently a new religion; A dark(er) religion. One that had it’s origins even further back than any other known religion. This was what made it the most appealing. Apart from the fact that it didn’t shy away from advising to do what was necessary. This religion had one God, Rae, the Dark Lord. Some even called him the Fallen Angel and the Creator of Creators, but from where these names have come from, Lynn had no idea.&lt;/p&gt;
&lt;p&gt;It all sounded so familiar to her. Most of it was eerily familiar, in fact, because she was the one to write it. She and Rox. Oh, how helpless Rox was, dying in a pool of her own blood. And Lynn did nothing, could do nothing but watch. She remembered being injured, her head bleeding a river of it’s own. And yet, here she was, practically unscratched in a world so similar, yet completely different.&lt;/p&gt;
&lt;p&gt;This was all secondary though. There was something else, something about this new religion that didn’t sound right to her. She had seen huge temples on the way to the shelter, all dedicated to Rae. And the appearance of the mammoth statues on the top. She had described them before, seen them before. Somehow, the religion that she had made, a religion that she invented, was now the epicenter of everything. &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;This is my first attempt at fiction. I would be happy to hear your comments and feedback on this. &lt;/p&gt;
&lt;p&gt;And do let me know if you want to hear this story further. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Remote testing and debugging of iOS apps]]></title><link>https://pulkitgoyal.in/remote-testing-and-debugging-of-ios-apps</link><guid isPermaLink="false">https://pulkitgoyal.in/remote-testing-and-debugging-of-ios-apps</guid><pubDate>Wed, 01 Aug 2018 01:20:33 GMT</pubDate><content:encoded>&lt;p&gt;One problem that many iOS app developers have encountered is how to debug iOS programs being run on remote iOS devices. Good thing if you can connect an iPhone, iPad, iPod, etc. directly to your development computer. But what should you do if you don’t have the iOS device around to plug it into your local machine? Is there any way to get remote access to the device and applications it’s running?&lt;/p&gt;
&lt;h2&gt;Xcode to the rescue - debug iOS apps wirelessly&lt;/h2&gt;
&lt;p&gt;Thanks to the relatively new feature found in Xcode 9, iOS app developers are able to test their creations remotely. That means you don’t need to always physically connect and disconnect the device for app installation and debugging, you’re able to just access the required iOS gadget over the network.&lt;/p&gt;
&lt;p&gt;However, before choosing this method you should note that:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In order to set up remote debugging, you’ll still need to physically connect the iOS device to your development machine.&lt;/li&gt;
&lt;li&gt;Mac running Xcode and the iOS device you want to connect remotely must share the same local network. Otherwise, you won’t be able to use this feature.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;FlexiHub: connect to remote iOS devices from anywhere&lt;/h2&gt;
&lt;p&gt;If the feature found in Xcode does not fit your purposes, you definitely should give a try to FlexiHub.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.flexihub.com/&quot;&gt;FlexiHub&lt;/a&gt; caught my eye precisely because the software works equally well across any network and is extremely simple to install and use.&lt;/p&gt;
&lt;p&gt;FlexiHub’s unique port virtualization technology and its intuitive GUI are its strong points. The app is designed to virtualize iOS devices and redirect them over the network. That means you don’t need to have the target device near your local PC to be able to access its functionality and contents. This could be a significant advantage for mobile app developers.&lt;/p&gt;
&lt;h2&gt;Here’s how FlexiHub works:&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;When you first join the service, it suggests that you &lt;a href=&quot;https://flexihub.eltima.com/user/registration/&quot;&gt;create an account and sign up for a free trial&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Then, install FlexiHub on the local Mac running the debugger as well as on the remote machine where the iOS device is connected physically.&lt;/li&gt;
&lt;li&gt;After that, start the software on the local machine and log into the FlexiHub account.&lt;/li&gt;
&lt;li&gt;Repeat the previous step for the remote computer.&lt;/li&gt;
&lt;li&gt;In the software interface, you’ll see this device available for connection. All you need to do is click “Connect”.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;After that, the remote iOS device will appear in the Device Manager of your local computer like it was directly connected to that machine.&lt;/p&gt;
&lt;p&gt;Again, this is all about letting you go straight to app debugging on a remote device in the simplest and fastest way.&lt;/p&gt;
&lt;p&gt;If FlexiHub is not exactly what you are looking for right now, here is a simple step-by-step instruction on how to enable remote debugging in Xcode:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;First, you need to make sure that you’re running Xcode 9.0 or later, macOS 10.12.4 or later, and iOS 11.0 or later.&lt;/li&gt;
&lt;li&gt;Then, to set up iPhone, iPad, or iPod touch, open your project on Xcode.&lt;/li&gt;
&lt;li&gt;Choose “Window” &gt; “Devices and Simulators”.&lt;/li&gt;
&lt;li&gt;Click “Devices” in the invoked window.&lt;/li&gt;
&lt;li&gt;Connect the required device to your Mac with the help of a USB cable.&lt;/li&gt;
&lt;li&gt;In the left column, select the device and enable “Connect via network” in the detail area.&lt;/li&gt;
&lt;li&gt;Now, Xcode will pair with your device. If the connection is established, you’ll see a network icon next to the device in the left column.&lt;/li&gt;
&lt;li&gt;Finally, disconnect the device.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here you go! Now, everything is set up to start the remote debug of your iOS app.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Better Background Jobs in Rails]]></title><link>https://pulkitgoyal.in/better-background-jobs-in-rails</link><guid isPermaLink="false">https://pulkitgoyal.in/better-background-jobs-in-rails</guid><pubDate>Fri, 20 Jul 2018 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Scalability is something that is deemed easily achievable in the current time. &lt;a href=&quot;https://heroku.com/&quot;&gt;Heroku&lt;/a&gt; and &lt;a href=&quot;https://aws.amazon.com/&quot;&gt;AWS&lt;/a&gt; can give us that extra power required to scale our apps with a few clicks and we are good to go. But true scalability lies in code. One common approach to achieving fast response times is to delegate time-consuming tasks to a (group of) background worker(s) that can possibly work in parallel and knock off the heavy slabs taking the load off the web process.&lt;/p&gt;
&lt;p&gt;What we usually overlook is the load these job workers need to handle. At our organization, we enqueue background jobs from a lot of &lt;code class=&quot;language-text&quot;&gt;after_save&lt;/code&gt; callbacks. When you reach a complex schema with objects saving their children, it’s hard to keep track of how many jobs even a small change could trigger. And a lot of times, most of these jobs are duplicate ones caused by the saving of the same object from different links.&lt;/p&gt;
&lt;p&gt;How do we solve this? It can’t be easy tracking all those callbacks and prevent multiple jobs, right? The solution, as it turned out, was much simpler. A custom job adapter that could knock away those duplicate jobs keeping only one copy per job. We were able to decrease our job counts by more than 50% with this simple adapter. How did we make this adapter? Let’s check out the original delayed jobs adapter first:&lt;/p&gt;
&lt;script src=&quot;https://gist-it.appspot.com/github/rails/rails/blob/b1fbb6688c9e7b1909ca3ab71691822fc32daf1c/activejob/lib/active_job/queue_adapters/delayed_job_adapter.rb&quot;&gt;&lt;/script&gt;
&lt;p&gt;Great, looks simple. All we need is to override &lt;code class=&quot;language-text&quot;&gt;enqueue&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;enqueue_at&lt;/code&gt; methods to find duplicate jobs and skip enqueueing them. If you study the format of the handler in the &lt;code class=&quot;language-text&quot;&gt;delayed_jobs&lt;/code&gt; table, it’s pretty easy to find duplicate jobs. All we need is to check for the job class and the passed arguments. Here’s an example of how simply this can be implemented.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;ruby&quot;&gt;&lt;pre class=&quot;language-ruby&quot;&gt;&lt;code class=&quot;language-ruby&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;already_queued&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
  query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;Delayed&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;Job&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;handler ilike &apos;%&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;%&apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:locked_at&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token symbol&quot;&gt;:locked_by&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; update_query_for_arguments&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  query&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;any&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;token method-definition&quot;&gt;&lt;span class=&quot;token function&quot;&gt;update_query_for_arguments&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;query&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; arguments&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  arguments&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;a&lt;span class=&quot;token operator&quot;&gt;|&lt;/span&gt;
    query &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; query&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;where&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;handler ilike &apos;%&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter tag&quot;&gt;#{&lt;/span&gt;a&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;try&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token symbol&quot;&gt;:to_global_id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; a&lt;span class=&quot;token delimiter tag&quot;&gt;}&lt;/span&gt;&lt;/span&gt;%&apos;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;
  query
&lt;span class=&quot;token keyword&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I have left &lt;code class=&quot;language-text&quot;&gt;update_query_for_arguments&lt;/code&gt; to be very simple, but it can be extended to support array and hash arguments if you need it.&lt;/p&gt;
&lt;p&gt;Finally, time for our shiny new adapter that would automatically discard the duplicate jobs coming in.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;module ActiveJob
  module QueueAdapters
    class UniqDelayedJobAdapter &amp;lt; ActiveJob::QueueAdapters::DelayedJobAdapter
      class &amp;lt;&amp;lt; self
        alias super_enqueue enqueue
        alias super_enqueue_at enqueue_at

        def enqueue(job)
          return if job.try(:already_queued?)
          super_enqueue(job)
        end

        def enqueue_at(job, timestamp)
          return if job.try(:already_queued?)
          super_enqueue_at(job, timestamp)
        end
      end
    end
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, enable the adapter at a convenient location (e.g. &lt;code class=&quot;language-text&quot;&gt;application.rb&lt;/code&gt; or one of the environment specific initializers) and you are good to go:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;config.active_job.queue_adapter = :uniq_delayed_job&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now you can enqueue to your job queue without worrying about duplicates eating up your hours for the worker.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;MyJob.perform_later(my_arg) # Enqueued MyJob to delayed_jobs
MyJob.perform_later(my_arg) # No longer enqueues another job unless the previous one had already started processing&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Update Localization on iOS at Runtime]]></title><link>https://pulkitgoyal.in/update-localization-on-ios-at-runtime</link><guid isPermaLink="false">https://pulkitgoyal.in/update-localization-on-ios-at-runtime</guid><pubDate>Mon, 25 Dec 2017 08:19:24 GMT</pubDate><content:encoded>&lt;p&gt;iOS apps will run on many devices in many regions. To reach the most users, your application should handle text, audio files, numbers, currency, and graphics in ways appropriate to the locales where your application will be used. The framework automatically selects the resources that best match the device. Such a behavior is ok for most apps. But for some specialized apps, it might be required to change the localization at runtime, e.g. through in-app Settings. &lt;/p&gt;
&lt;h2&gt;In-app localization&lt;/h2&gt;
&lt;p&gt;On iOS, there are a lot of arguments as to why this is not a good pattern. Generally, from a programmatic point of view, it’s not easy if you are using Storyboards and there are a lot of hacks involved. Anyway, if this is something that you absolutely must include in your app, you are at the right place. &lt;/p&gt;
&lt;h2&gt;Loading localized string in code&lt;/h2&gt;
&lt;p&gt;Let’s get the simple things out of the way first. To load localized strings in code, you first need to load the bundle for the appropriate language. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Bundle&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main
&lt;span class=&quot;token comment&quot;&gt;// Try to load from language specific bundle&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forResource&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;fr&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ofType&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lproj&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; bundle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Bundle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;localizedString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello, World&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; 
&lt;span class=&quot;token comment&quot;&gt;// Load from Base bundle&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forResource&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;LCLBaseBundle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ofType&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lproj&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; bundle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Bundle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;localizedString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello, World&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Persist selected language&lt;/h2&gt;
&lt;p&gt;The next step that is pretty straightforward is to persist the user’s selection of language in &lt;code class=&quot;language-text&quot;&gt;UserDefaults&lt;/code&gt;. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token builtin&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selectedLanguage&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;PGCurrentLanguageKey&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token builtin&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;synchronize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You need to read the USerDefaults later whenever the localization of a string is required. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;currentLanguage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; currentLanguage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;PGCurrentLanguageKey&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; currentLanguage
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;defaultLanguage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above two are so common, that there are already libraries available to handle this stuff for you. &lt;a href=&quot;https://github.com/marmelroy/Localize-Swift&quot;&gt;Localize-Swift&lt;/a&gt; is one such library that handles this and provides very clean helpers to help your localization needs. With it, you can write things like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;textLabel&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;localized&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token builtin&quot;&gt;Localize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCurrentLanguage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fr&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token builtin&quot;&gt;Localize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resetCurrentLanguageToDefault&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Storyboard Localization&lt;/h2&gt;
&lt;p&gt;If you start using this, one thing that you will notice straight away is that it doesn’t help with Storyboard localization. Why? The initial locale on the Storyboard is read right after you load the storyboard. This could be done in your &lt;code class=&quot;language-text&quot;&gt;AppDelegate&lt;/code&gt; if you manually load the storyboard and set the window or automatically by &lt;code class=&quot;language-text&quot;&gt;UIKit&lt;/code&gt; if you have set the Storyboard in your project settings. &lt;/p&gt;
&lt;h3&gt;Restart app after language change&lt;/h3&gt;
&lt;p&gt;One possible solution for localized storyboards is to update the &lt;code class=&quot;language-text&quot;&gt;AppleLanguages&lt;/code&gt; key in UserDefaults when the user changes the language in the app and then force the user to restart the app. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token builtin&quot;&gt;NotificationCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addObserver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selector&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #&lt;span class=&quot;token function&quot;&gt;selector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;languageUpdated&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;NSNotification&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;LCLLanguageChangeNotification&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; object&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;languageUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Localize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentLanguage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;AppleLanguages&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;UserDefaults&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;standard&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;synchronize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// TODO: Show alert asking user to restart the app for language change to take effect&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Use stubs in storyboard&lt;/h3&gt;
&lt;p&gt;The second alternative is to just use stubs for all text in the storyboard and then set the text manually in code. This might be very cumbersome for even standard size apps, but is definitely the best way to go to allow a perfect flow for the user when he changes the language. &lt;/p&gt;
&lt;h3&gt;Reload Storyboard locally after a language update&lt;/h3&gt;
&lt;p&gt;This requires an extension on &lt;code class=&quot;language-text&quot;&gt;Bundle&lt;/code&gt; that tricks it into loading strings from the current localization instead of the cached locale that UIKit selects when starting the app. Create an extension on Bundle and override  &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;localizedString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; table tableName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Bundle&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bundle &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forResource&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Localize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentLanguage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ofType&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;lproj&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; bundle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Bundle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;path&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; bundle&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;localizedString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; tableName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;localizedString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;forKey&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; value&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; table&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; tableName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This makes the Storyboard load strings from the updated locale for any view controllers that are constructed after the change. In order to change the existing views, you still need to either change them manually, reconstruct the current view controller (dismiss/pop and present/push again) or simple send him back to the original view controller of the app. In your &lt;code class=&quot;language-text&quot;&gt;AppDelegate&lt;/code&gt;, after a language change, do this: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; storybaord &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UIStoryboard&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Main&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bundle&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rootViewController &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; storybaord&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;instantiateInitialViewController&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Login and Authenticated Sections to React/React-Native App]]></title><link>https://pulkitgoyal.in/adding-authenticated-sections-to-react-react-native-app</link><guid isPermaLink="false">https://pulkitgoyal.in/adding-authenticated-sections-to-react-react-native-app</guid><pubDate>Sun, 12 Nov 2017 07:43:14 GMT</pubDate><content:encoded>&lt;p&gt;Most single page apps are likely to have some authenticated sections that should be inaccessible unless the user has identified itself. Adding authentication can be a non-trivial challenge for any app and though it’s not very difficult, there are several possible ways to approach this. &lt;/p&gt;
&lt;p&gt;The most obvious and the arguably one that offers best security is to have the authentication separated from the app. But this either requires maintaining two different versions of the app for the authenticated and non-authenticated sections or requires server-side page flows. However, this is not always possible, for example when you want to have an installed app that needs to work offline. &lt;/p&gt;
&lt;p&gt;This post describes an architecture using React, &lt;a href=&quot;https://reacttraining.com/react-router/&quot;&gt;react-router&lt;/a&gt; to handle login and authenticated sections of an app. &lt;/p&gt;
&lt;p&gt;With React Router, Route is just a component, just like div. So it is possible to nest multiple routes inside another &lt;code class=&quot;language-text&quot;&gt;Route&lt;/code&gt; as if it was a div. This makes it really simple to abstract all our authentication logic to one component that could allow/disallow the users to access all nested sections. &lt;/p&gt;
&lt;p&gt;This means that you can layout your app like this&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;App&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Switch&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/login&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;LoginPage&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;AuthenticatedRoutes&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Switch&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;App&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Simple enough, right? &lt;/p&gt;
&lt;p&gt;It’s also really easy to implement the &lt;code class=&quot;language-text&quot;&gt;AuthenticatedRoutes&lt;/code&gt; component to redirect to login in case the user tries to access one of the nested pages. All of it can fit in 30 lines: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;AuthenticatedRoutes&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;componentDidMount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; isLoggedIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; redirectToLogin &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;isLoggedIn&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;redirectToLogin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; isLoggedIn&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sidebar &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;isLoggedIn&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Header&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Sidebar&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;section&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;exact&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;IndexPage&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/route1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;exact&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Route1Page&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/route2&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
                &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;/route2/nested1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;Route2Nested1Page&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
              &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
            &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Route&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
          &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;section&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This will take care of redirecting to login each time this component is mounted when the user is not logged in. The &lt;code class=&quot;language-text&quot;&gt;redirectToLogin&lt;/code&gt; action takes care of this and again, it is very simple to write: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;export function redirectToLogin() {
  return (dispatch: (action: actionType) =&amp;gt; void) =&amp;gt; {
    dispatch(push(&amp;#39;/login&amp;#39;));
  };
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The dynamic route philosophy from react router makes laying out the authentication logic really simple and is very easy to understand with most of the logic in a single component. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Resuming downloads on iOS]]></title><link>https://pulkitgoyal.in/resuming-downloads-on-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/resuming-downloads-on-ios</guid><pubDate>Sat, 28 Oct 2017 14:29:59 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;With the increasing amount of data being used by mobile apps, it’s becoming common for most apps to download data to support offline functions. The downloaded data could be for additional textures for supporting complex games, ebooks for readers or music/video files for video/music players or companion guide apps that are becoming the de-facto standard for every big tourist attraction.&lt;/p&gt;
&lt;p&gt;In the &lt;a href=&quot;https://pulkitgoyal.in/downloading-files-on-ios&quot;&gt;previous post&lt;/a&gt;, I described how to add simple file downloads in your app in less than 100 lines of code. Most often, the apps implementing their own download managers forget one very important aspect of this process. Pausing and resuming downloads. As the sizes of download packages increase, it becomes even more important to allow users to pause the download and resume later when they have better internet connectivity.&lt;/p&gt;
&lt;h2&gt;Downloading files on iOS&lt;/h2&gt;
&lt;p&gt;For the complete code to download files on iOS, check out the &lt;a href=&quot;https://pulkitgoyal.in/downloading-files-on-ios&quot;&gt;previous post&lt;/a&gt;. We get a &lt;code class=&quot;language-text&quot;&gt;downloadRequest&lt;/code&gt; when initiating a download with Alamofire. In order to allow users to cancel the download, all we need is to cancel the request using &lt;code class=&quot;language-text&quot;&gt;downloadRequest.cancel()&lt;/code&gt; when the user presses Cancel.&lt;/p&gt;
&lt;h3&gt;Save resume data&lt;/h3&gt;
&lt;p&gt;When a download is cancelled (either on user’s request or due to a network or internal error), Alamofire invokes the response handler where we can handle the response error and process resume data. Neither iOS nor Alamofire, automatically save this resume data to resume the download later. In order to support resuming downloads, the first step is to save the resume data in the cache so that this can be used later when initiating the download again.&lt;/p&gt;
&lt;p&gt;Let’s see how to handle resume data in &lt;strong&gt;response block&lt;/strong&gt; from Alamofire.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; error &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; defaultDownloadResponse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Download Failed with error - &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;error&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; resumeData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; defaultDownloadResponse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resumeData &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;Shared&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataCache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resumeData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We will be using data cache from &lt;a href=&quot;https://github.com/Haneke/HanekeSwift&quot;&gt;Haneke&lt;/a&gt; in this post to store the resume data. If you are using another library or have rolled out your own cache implementation, you need to change the occurrences of &lt;code class=&quot;language-text&quot;&gt;Shared.dataCache&lt;/code&gt; to fit your implementation.&lt;/p&gt;
&lt;h3&gt;Resume download from saved data&lt;/h3&gt;
&lt;p&gt;The next step is to provide this resume data when trying to resume the download.&lt;/p&gt;
&lt;p&gt;First, fetch the resume data from the cache.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token builtin&quot;&gt;Shared&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataCache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onSuccess &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;resumeData &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;with&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resumeData&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onFailure &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now provide this data when initiating the download. Alamofire makes this really simple. All we need is to add the additional &lt;code class=&quot;language-text&quot;&gt;resumingWith&lt;/code&gt; param when creating the request.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token builtin&quot;&gt;Alamofire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resumingWith&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resumeData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Putting everything together&lt;/h3&gt;
&lt;p&gt;Let’s put everything together into our shiny new &lt;code class=&quot;language-text&quot;&gt;beginDownload&lt;/code&gt; method.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;beginDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token builtin&quot;&gt;UIApplication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shared&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isIdleTimerDisabled &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadProgressView&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startProgress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; duration&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;SYSTEM_VERSION_LESS_THAN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;version&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10.0&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;SYSTEM_VERSION_GREATER_THAN&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;version&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;10.2&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;Shared&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataCache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onSuccess &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;resumeData &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;with&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resumeData&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onFailure &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;startDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;with resumeData&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; destination&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;DownloadRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;DownloadFileDestination&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;temporaryURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; suggestedFileName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;suggestedFilename &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; directory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;tempDirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;directory &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; suggestedFileName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; downloadedFilePath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exists &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
          &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fileURLWithPath&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; downloadedFilePath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rawValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;removePreviousFile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createIntermediateDirectories&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; e &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to get temporary directory - &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;e&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;downloadedFileURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;DownloadRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;suggestedDownloadDestination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;temporaryURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;downloadedFileURL&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;absoluteString&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;downloadedFileURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;removePreviousFile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createIntermediateDirectories&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; resumeData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; resumeData &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    downloadRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Alamofire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resumingWith&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resumeData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    downloadRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Alamofire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  downloadRequest&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadProgress &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;progress &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;async &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadProgressView&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startProgress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CGFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;progress&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fractionCompleted &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; duration&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defaultDownloadResponse &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// TODO Handle cancelled error&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; error &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; defaultDownloadResponse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Download Failed with error - &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;error&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; resumeData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; defaultDownloadResponse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resumeData  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token builtin&quot;&gt;Shared&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataCache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; resumeData&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Downloaded file successfully to &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;downloadedFilePath&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;unzipFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;at&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; downloadedFilePath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s all you need for supporting pause and resume on your iOS apps. The next time you are integrating download in an app, check out this post and do a favor to your users by integrating the resume function.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Downloading Files in iOS]]></title><link>https://pulkitgoyal.in/downloading-files-on-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/downloading-files-on-ios</guid><pubDate>Mon, 18 Sep 2017 14:40:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;With the increasing amount of data being used by mobile apps, it’s becoming common for most apps to download data to support offline functions. The downloaded data could be for additional textures for supporting complex games, ebooks for readers or music/video files for video/music players or companion guide apps that are becoming the de-facto standard for every big tourist attraction. &lt;/p&gt;
&lt;p&gt;Most often, the apps implementing their own download managers forget one very important aspect of this process. Pausing and resuming downloads. As the sizes of download packages increase, it becomes even more important to allow users to pause the download and resume later when they have better internet connectivity. &lt;/p&gt;
&lt;h2&gt;Downloading Files&lt;/h2&gt;
&lt;p&gt;iOS has a great support for file downloads using the Foundation’s &lt;a href=&quot;https://developer.apple.com/documentation/foundation/nsurlconnection&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;NSURLConnection&lt;/code&gt;&lt;/a&gt;. An NSURLConnection object lets you load the contents of a URL by providing a URL request object. The interface for NSURLConnection is sparse, providing only the controls to start and cancel asynchronous loads of a URL request. &lt;/p&gt;
&lt;h3&gt;Alamofire&lt;/h3&gt;
&lt;p&gt;Given the huge developer community, there are several tools and libraries already built around to make your life easier. Rather than reinventing the wheel with boilerplate around &lt;code class=&quot;language-text&quot;&gt;NSURLConnection&lt;/code&gt;, let’s try to set up downloads using &lt;a href=&quot;https://github.com/Alamofire/Alamofire&quot;&gt;Alamofire&lt;/a&gt; which greatly simplifies the download tasks. &lt;/p&gt;
&lt;p&gt;From the documentation, it’s very simple to &lt;a href=&quot;https://github.com/Alamofire/Alamofire#downloading-data-to-a-file&quot;&gt;initiate file downloads&lt;/a&gt; using Alamofire using &lt;code class=&quot;language-text&quot;&gt;Alamofire.download&lt;/code&gt;. To select a download destination, we need to use the &lt;code class=&quot;language-text&quot;&gt;DownloadFileDestination&lt;/code&gt; block to return the file url download should be stored at. Finally, for listening to download progress updates, we can add the &lt;code class=&quot;language-text&quot;&gt;downloadProgress&lt;/code&gt; block. One thing to take care of in the progress block is that it is invoked on the background thread, so if you want to make some changes to the UI (e.g. updating a progress view), use &lt;code class=&quot;language-text&quot;&gt;DispatchQueue.main.async&lt;/code&gt; to execute the updates on UI thread. &lt;/p&gt;
&lt;p&gt;Let’s put everything together: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;beginDownload&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token builtin&quot;&gt;UIApplication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shared&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isIdleTimerDisabled &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;

   &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadProgressView&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setProgress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; animationDuration&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
   
   &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; destination&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;DownloadRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;DownloadFileDestination&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;temporaryURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
     &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; suggestedFileName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;suggestedFilename &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
       &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; directory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;tempDirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;directory &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; suggestedFileName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
           &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; downloadedFilePath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exists &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;deleteFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
           &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fileURLWithPath&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; downloadedFilePath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rawValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;removePreviousFile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createIntermediateDirectories&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
       &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; e &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to get temporary directory - &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;e&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
     
     &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;downloadedFileURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;DownloadRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;suggestedDownloadDestination&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;temporaryURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;downloadedFileURL&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;absoluteString&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;downloadedFileURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;removePreviousFile&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;createIntermediateDirectories&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

   downloadRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Alamofire&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;destination&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadProgress &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;progress &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
     &lt;span class=&quot;token builtin&quot;&gt;DispatchQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;main&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;async &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadProgressView&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setProgress&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CGFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;progress&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fractionCompleted &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; animationDuration&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;response &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; defaultDownloadResponse &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
     &lt;span class=&quot;token comment&quot;&gt;// TODO: Handle cancelled error&lt;/span&gt;
     &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; error &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; defaultDownloadResponse&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
         log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;warning&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Download Failed with error - &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;error&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Download&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
     &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
     &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; downloadedFilePath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;downloadedFilePath &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
     log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Downloaded file successfully to &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;downloadedFilePath&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;token comment&quot;&gt;// TODO: Handle downloaded file&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
 &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Common File Utilities&lt;/h3&gt;
&lt;p&gt;I often use common utility functions to access directory locations throughout the app (This is using &lt;code class=&quot;language-text&quot;&gt;Path&lt;/code&gt; from &lt;a href=&quot;https://github.com/nvzqz/FileKit&quot;&gt;FileKit&lt;/a&gt;, so make sure you add it in &lt;code class=&quot;language-text&quot;&gt;Podfile&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;Cartfile&lt;/code&gt; if you plan to use these utilities too). &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utils&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tempDirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Path&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;directoryInsideDocumentsWithName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;temp&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;directoryInsideDocumentsWithName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; create&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Bool&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Path&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; directory &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;NSSearchPathForDirectoriesInDomains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;documentDirectory&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;userDomainMask&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; name
   &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; create &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;directory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exists &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
     &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; directory&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createDirectory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
   &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; directory
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s all you need to integrate a simple download component in your app. To learn more about downloading files, check out the next post that describes how to add support for pausing and resuming the downloads without redownloading the already downloaded content. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Hyperion Cantos]]></title><link>https://pulkitgoyal.in/hyperion-cantos</link><guid isPermaLink="false">https://pulkitgoyal.in/hyperion-cantos</guid><pubDate>Mon, 05 Jun 2017 11:04:58 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/172a9241c1e30bb19a13fe6d5a5870ef/shrike_wyuqw1.gif&quot;&gt;&lt;/p&gt;
&lt;p&gt;This &lt;a href=&quot;https://www.goodreads.com/series/40461-hyperion-cantos&quot;&gt;four-part masterpiece&lt;/a&gt; by Dan Simmons is one of the best series I have read. I had heard amazing reviews about this and this was right in the spot with the kind of books I like to read. I started reading the Hyperion Cantos series this year and I can’t recommend it enough. &lt;/p&gt;
&lt;p&gt;The first book in the series, &lt;a href=&quot;https://www.goodreads.com/book/show/77566.Hyperion&quot;&gt;Hyperion&lt;/a&gt;, tells the story of seven pilgrims who must face the creature called Shrike in the Time Tombs, huge structures that move backward through time. It has masterful storytelling filled with lots of surprises, action, excitement, and sci-fi. The earth is destroyed and humanity is spread across hundreds of planets across the universe. &lt;/p&gt;
&lt;p&gt;Most of the worlds are connected through &lt;em&gt;Farcaster Portals&lt;/em&gt; (as big as huge arcs and as small as a door) that can teleport you from one planet to the other. So if you are really rich, you could have a home that has a bedroom looking over the ocean on &lt;em&gt;Maui Covenant&lt;/em&gt; and the terrace opening into vast forests on &lt;em&gt;God’s Grove&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;Space travel is not dead, so you can travel through space in large spaceships, but be aware of the time debt accrued when traveling via &lt;em&gt;Hawking Drive&lt;/em&gt;. What are a few months for you could be several years/decades for your family and friends. &lt;/p&gt;
&lt;p&gt;Anyway, enough about the technology. The book tells the story of seven pilgrims on a journey to face the Shrike. The one who survives would get a wish from the Shrike. &lt;/p&gt;
&lt;p&gt;The second book, &lt;a href=&quot;https://www.goodreads.com/book/show/77565.The_Fall_of_Hyperion&quot;&gt;The Fall of Hyperion&lt;/a&gt; picks up where the first one left. On the world of Hyperion, the mysterious Time Tombs are opening. And the secrets they contain mean that nothing—nothing anywhere in the universe—will ever be the same. This is a tale of treachery and humanity’s fight to survive. I cannot describe this in more details without spoiling the first book, but this in every way as good as the first one. &lt;/p&gt;
&lt;p&gt;The third and fourth books are set a couple of centuries after the fall. These are not as much a continuation of the story that finished (or rather didn’t finish) with The Fall of Hyperion, but it comes full circle in the end and everything is wonderfully explained. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.goodreads.com/book/show/3977.Endymion&quot;&gt;Endymion&lt;/a&gt;, the third part of the epic saga tells the story of love and memory, triumph and terror. It is set in a world where the cruciform has spread throughout the galaxy, has been tamed and promises everyone a life after death, immortality without any of the side effects that the Bikura went through. &lt;/p&gt;
&lt;p&gt;It’s a journey of a messiah and her protector running from the religious missionaries along the (now) dead River Tethys. A story that finishes at the same place where the started, it will certainly leave you wondering and excited for the finale to come. &lt;/p&gt;
&lt;p&gt;The epic finale, &lt;a href=&quot;https://www.goodreads.com/book/show/11289.The_Rise_of_Endymion&quot;&gt;The Rise of Endymion&lt;/a&gt; follows the story of the messiah and her protector to new worlds, new dangers, and the Pax. Again, I can’t say more without spoiling it for you, but this is a fitting finale to the series which is guaranteed to leave you in tears. Very thrilling, filled with fun and surprises. A great tale about politics, AI, humanity and love.&lt;/p&gt;
&lt;p&gt;Happy reading! &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Audio Processing on iOS using Aubio]]></title><link>https://pulkitgoyal.in/audio-processing-on-ios-using-aubio</link><guid isPermaLink="false">https://pulkitgoyal.in/audio-processing-on-ios-using-aubio</guid><pubDate>Sat, 06 May 2017 14:17:02 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://aubio.org/&quot;&gt;Aubio&lt;/a&gt; is a tool designed for the extraction of annotations from audio signals. Its features include segmenting a sound file before each of its attacks, performing pitch detection, tapping the beat and producing midi streams from live audio.&lt;/p&gt;
&lt;p&gt;It comes prebuilt for iOS in form of a framework that can be just dragged into a Xcode project to get going. This post will touch some basics of working with the aubio framework on iOS.
Let’s walk through a simple beat detection task with aubio. &lt;/p&gt;
&lt;p&gt;The first step is the easiest &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; aubio&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To detect beats, we need to create a &lt;a href=&quot;https://aubio.org/doc/0.4.0/tempo_8h.html#aaa49f5d6554904a452d031775f385521&quot;&gt;tempo detector&lt;/a&gt;. You need to pass a method, the buffer size, hop size (number of frames between two consecutive runs. A good value is usually buffer size / 2) and the sample rate.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; tempo&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;COpaquePointer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_aubio_tempo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It’s usually a good idea to ignore long silences. It has a method to do just that that accepts the pointer to the tempo detector and a float silence threshold in dB.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token function&quot;&gt;aubio_tempo_set_silence&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tempo&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; silenceThreshold&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to perform detection, we need either to feed raw data to the detector. &lt;/p&gt;
&lt;p&gt;If you want to run this on a file, it’s easy using an aubio source: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; samples &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; source &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_aubio_source&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/path/to/file.wav&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; read &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; uint_t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;aubio_source_do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; samples&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;read &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;aubio_tempo_do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tempo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; samples&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; out&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fvec_get_sample&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; beat_time &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Float&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;total_frames&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samplerate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;format&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;beat at %.2f&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; beat_time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;read &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;del_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;del_aubio_tempo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tempo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;del_aubio_source&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;del_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samples&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But who wants to run on a file, it boring! aubio is optimized to even run the algorithms on real-time audio coming from the microphone. First step is to get raw data from the microphone. There’s a really nice gist to get this done. &lt;/p&gt;
&lt;script src=&quot;https://gist.github.com/hotpaw2/ba815fc23b5d642705f2b1dedfaf0107.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;Use this, but update the &lt;code class=&quot;language-text&quot;&gt;processMicrophoneBuffer&lt;/code&gt; to feed the data to aubio: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setupAubio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samplerate&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UInt32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    samples &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sampleSize&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    tempo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_aubio_tempo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;default&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sampleSize&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; samplerate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;aubio_tempo_set_silence&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tempo&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; silenceThreshold&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;processMicrophoneBuffer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;inputDataList &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UnsafeMutablePointer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;AudioBufferList&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; frameCount &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UInt32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; samples &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; samples&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tempo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tempo &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; out &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;new_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; sampleCount&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UInt32&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataArray&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;i  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// copy left  channel sample&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dataArray&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;i&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;   &lt;span class=&quot;token comment&quot;&gt;// copy right channel sample&lt;/span&gt;
        
        &lt;span class=&quot;token function&quot;&gt;fvec_set_sample&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samples&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sampleCount&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        sampleCount &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; sampleCount &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; sampleSize &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;aubio_tempo_do&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;onset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; samples&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; out&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fvec_get_sample&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// Yay! A BEAT!!!&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            sampleCount &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;del_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;out&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;stopRecording&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; tempo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; tempo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; samples &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; samples &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;del_aubio_tempo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tempo&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;del_fvec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;samples&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tempo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;samples &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note: Make sure you clean up the pointers in &lt;code class=&quot;language-text&quot;&gt;stopRecording&lt;/code&gt; to avoid memory leaks. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[iOS Music Player on the Lock Screen]]></title><link>https://pulkitgoyal.in/ios-music-player-on-the-lock-screen</link><guid isPermaLink="false">https://pulkitgoyal.in/ios-music-player-on-the-lock-screen</guid><pubDate>Fri, 05 Aug 2016 08:57:30 GMT</pubDate><content:encoded>&lt;p&gt;Building a music player app and want the system to display the current track information on the device lock screen and in the multimedia controls? You can use a now playing info center to set now-playing information for media being played by your app. This takes care of showing the music info and playback controls on the lock screen. If the user directs playback of your media to Apple TV via AirPlay, the now-playing information appears on the television screen. If the user connects a device to an iPod accessory, such as in a car, the accessory may display now-playing information.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPNowPlayingInfoCenter_Class/&quot;&gt;MPNowPlayingInfoCenter&lt;/a&gt; is the class that controls this information. The information you can specify includes a subset of the properties available in the media item class (&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPMediaItem_ClassReference/index.html#//apple_ref/occ/cl/MPMediaItem&quot;&gt;MPMediaItem&lt;/a&gt;), as well as some properties specific to this class. You do not have direct control over which information is displayed, or its formatting. You set the values of the now playing info center dictionary according to the information you want to provide to the system. The system, or the connected accessory, handles the information’s display in a consistent manner for all apps.&lt;/p&gt;
&lt;p&gt;First, let’s discuss the setup required to register our app as a publisher for now playing information. The first requirement is to start receiving remote control events so the users can control the music from the playback controls on the lock screen. Next, we need to listen to the controls we will be handling and perform functions on our app accordingly based on these remote control events. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setupNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;UIApplication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedApplication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;beginReceivingRemoteControlEvents&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;MPRemoteCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;playCommand&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addTargetWithHandler &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resume&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Success&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;MPRemoteCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pauseCommand&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addTargetWithHandler &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pause&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Success&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;MPRemoteCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nextTrackCommand&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addTargetWithHandler &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Success&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;MPRemoteCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedCommandCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;previousTrackCommand&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;addTargetWithHandler &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;event &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Success&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The next part is actually publishing the information about the current track so that it can be displayed on the UI. Here’s a simple function that I use to update the information whenever a track changes or some important event occurs in the music player.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;artwork&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UIImage&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; currentItem &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nowPlayingInfo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;AnyObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; imageURL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;album&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;imageUrl &lt;span class=&quot;token keyword&quot;&gt;where&lt;/span&gt; artwork &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;Haneke&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Shared&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;imageCache&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; imageURL&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; success&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;MPNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nowPlayingInfo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPMediaItemPropertyTitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPMediaItemPropertyAlbumTitle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;album&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPMediaItemPropertyArtist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;album&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;artist&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPMediaItemPropertyPlaybackDuration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;duration&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPNowPlayingInfoPropertyElapsedPlaybackTime&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;progress
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; artwork &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; artwork &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token builtin&quot;&gt;MPNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;nowPlayingInfo&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;MPMediaItemPropertyArtwork&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MPMediaItemArtwork&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; artwork&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MPNowPlayingInfoCenter_Class/#//apple_ref/doc/constant_group/Additional_Metadata_Properties&quot;&gt;several metadata properties&lt;/a&gt; that you can specify on the now playing info center and it is recommended to set as many as possible. Note that here we use &lt;a href=&quot;https://github.com/Haneke/HanekeSwift&quot;&gt;Haneke&lt;/a&gt; for loading images from the network. In case we don’t have a cached image straight away, we can set the information without the artwork and then queue the updates again when we fetch the image. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Building a music player for iOS]]></title><link>https://pulkitgoyal.in/building-a-music-player-for-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/building-a-music-player-for-ios</guid><pubDate>Sat, 23 Jul 2016 10:32:52 GMT</pubDate><content:encoded>&lt;p&gt;There are already a few tutorials about building building an app that plays music on iOS. Why am I writing a whole new post about it then? Most of the existing tutorials focus on the really basic concepts about a music player app. This is going to be different. We will set up a full fledged music player with it’s own music library, ability to create custom playlists, streaming songs online etc. &lt;/p&gt;
&lt;p&gt;This is not a post about accessing the existing music on user’s device, so if you are looking for that, feel free to jump back to Google and resume your search. This also isn’t about the low level use of &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/MediaPlayer_Framework/index.html&quot;&gt;MediaPlayer framework&lt;/a&gt;. We will be using &lt;a href=&quot;https://github.com/tumtumtum/StreamingKit&quot;&gt;a library&lt;/a&gt; to handle this. &lt;/p&gt;
&lt;h2&gt;Building the Music Player&lt;/h2&gt;
&lt;p&gt;The first thing we are going to tackle in the post is creating the Music Player. We are using &lt;a href=&quot;https://github.com/tumtumtum/StreamingKit&quot;&gt;StreamingKit&lt;/a&gt;, so we have most of our work cut for us, but it still requires a bit of handling logic around it to implement all the features that a Music Player of this generation needs. &lt;/p&gt;
&lt;h3&gt;Initialization&lt;/h3&gt;
&lt;p&gt;To play music with StreamingKit, we need a &lt;code class=&quot;language-text&quot;&gt;STKAudioPlayer&lt;/code&gt;. Check out all the options for the audio player in the &lt;a href=&quot;https://github.com/tumtumtum/StreamingKit/blob/master/StreamingKit/StreamingKit/STKAudioPlayer.h&quot;&gt;source&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// MARK: Init&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;resetAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;resetAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;STKAudioPlayerOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;flushQueueOnSeek &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;enableVolumeMixer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    audioPlayer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// Set up audio player&lt;/span&gt;
    audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;meteringEnabled &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
    audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;volume &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;delegate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Handling a queue&lt;/h3&gt;
&lt;p&gt;Next thing a music player needs is to handle a queue of music files. You could get away with handling just one file per player and simplify the logic, but since we are focusing on a full fledged music player, we will see how to handle the queue. We create a class &lt;code class=&quot;language-text&quot;&gt;Track&lt;/code&gt; to handle the properties of each queue element. I will be skipping the implementation since it would be pretty specific depending on the app you are working on, but the main properties it should be supporting are &lt;code class=&quot;language-text&quot;&gt;identifier&lt;/code&gt; and a &lt;code class=&quot;language-text&quot;&gt;url&lt;/code&gt; (the URL for the music file, local/streaming).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;AlbumFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// MARK: Public API&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;playWithQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;AlbumFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;queue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; queue
    audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clearQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; url &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;playURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; i &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;queueURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;NSURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    currentIndex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index
    loop &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Controlling the playback&lt;/h3&gt;
&lt;p&gt;While we are adding a public API to the Music Player, let’s also add simple helper functions to control the playback. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    queue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    currentIndex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;AlbumFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;playURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;NSURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    currentIndex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentIndex &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;count&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;playWithQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; currentIndex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;prev&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    currentIndex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; currentIndex &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;playWithQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; currentIndex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Handling audio player events&lt;/h3&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;STKAudioPlayer&lt;/code&gt; communicates several events during playback to its delegate like when an item starts playing, finishes buffering, finishes playing or encounters an error. Let’s see how we can handle these events to perform meaningful operations in the music player. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A track starts playing: Update the local state to be communicated later to the UI&lt;/li&gt;
&lt;li&gt;A track finishes buffering: Update info in the now playing center (check out the next post to find out how to interface with the now playing center)&lt;/li&gt;
&lt;li&gt;Audio player state changes: Update the local state to be communicated later to the UI&lt;/li&gt;
&lt;li&gt;A track finishes playing: Switch to the next track&lt;/li&gt;
&lt;li&gt;Unexpected error occurs: Reset and try to play again or inform the user about the error depending on your app requirements. &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// MARK: Audio Player Delegate&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;audioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; didStartPlayingQueueItemId queueItemId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;indexOf &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; queueItemId &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentIndex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;audioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; didFinishBufferingSourceWithQueueItemId queueItemId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;updateNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;audioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stateChanged state&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayerState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; previousState&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayerState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; state &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Stopped&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; state &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; state &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Disposed&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;updateNowPlayingInfoCenter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;audioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; didFinishPlayingQueueItemId queueItemId&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; withReason stopReason&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayerStopReason&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; andProgress progress&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; andDuration duration&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Double&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;indexOf &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;currentlyPlayingQueueItemId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        currentIndex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; index
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; stopReason &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Eof&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; stopReason &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Error&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;stop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;resetAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;audioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;audioPlayer&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; unexpectedError errorCode&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayerErrorCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Error when playing music &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;errorCode&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;resetAudioPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;playWithQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;queue&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; currentIndex&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Supporting background audio&lt;/h3&gt;
&lt;p&gt;In order to play music while your app is in the background, you must do some &lt;a href=&quot;https://developer.apple.com/library/ios/qa/qa1668/_index.html&quot;&gt;additional set up&lt;/a&gt;. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Update your &lt;code class=&quot;language-text&quot;&gt;Info.plist&lt;/code&gt; file to include the audio in the &lt;code class=&quot;language-text&quot;&gt;UIBackgroundModes&lt;/code&gt; array.&lt;/li&gt;
&lt;li&gt;Initialize your AudioSession somewhere near the beginning of your app. A good point to do this is in &lt;code class=&quot;language-text&quot;&gt;AppDelegate.application(application:, didFinishLaunchingWithOptions:)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setupMusicPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;AVAudioSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setCategory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;AVAudioSessionCategoryPlayback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to setup audio&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Playing music&lt;/h3&gt;
&lt;p&gt;After we wrap everything up in a class (named &lt;code class=&quot;language-text&quot;&gt;MusicPlayer&lt;/code&gt; for the tutorial), we are good to go. Since you would normally be supporting just one instance of the music player in your app, it’s a good idea to create a singleton and use it all around your app. Here’s how you can set it up. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MusicPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;STKAudioPlayerDelegate&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; instance &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;MusicPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// …&lt;/span&gt;
    
    &lt;span class=&quot;token comment&quot;&gt;// MARK: Static&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sharedInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;MusicPlayer&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; instance
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s how you can use it from other parts of the UI. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token builtin&quot;&gt;MusicPlayer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sharedInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;playWithQueue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;tracks&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; indexPath&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;row&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Why you should start using RxSwift for iOS]]></title><link>https://pulkitgoyal.in/why-you-should-start-using-rxswift-for-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/why-you-should-start-using-rxswift-for-ios</guid><pubDate>Wed, 06 Jul 2016 14:39:30 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/53a9fd897b341a879f4cc8d8fe250c40/0b533/reactivex_xppuk4.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 500px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsSAAALEgHS3X78AAABQUlEQVQoz2O4JzyBAQTeik1gOCXQz7iXtx/M3wWlyQL/FScylDP2MYHZ2lMZrwpNZwSxuRnZyTBMdRKc/UNiIjcWJSCLGJEwDKDzIaCIoRcsuIG7v+oQX/+3O5KTdn+XnC4LEpNmEubB4Q50g1lQZPcJ9Ysu4ez/OputL++NVH/xOu55EUBhK6DT8oG0HRCbA7ElEFsAcRQQ2wOxDhA7AHEsSC2KRUu5J7A/E5tw4L/MRDNdhjredqbpTQwMHGZAqSQgzoEaUg7EnkAcBMQ+QJwJxClADLLcBm7gS7EJkMiQnqD5Q3LCkstCExYv5eh3A4tJ/WeAeocdGpZsUD4z1ABWtHCGgNfiE+Cc/95Twew1XFMYyUoyQFeB6e+SExj/SU2EBAHHRLCrBRh5yUuH3yUmQJPNBIaP4hBD/0lOJMssAPDDTyOIJB58AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;ReactiveX&quot;
        title=&quot;&quot;
        src=&quot;/static/53a9fd897b341a879f4cc8d8fe250c40/0b533/reactivex_xppuk4.png&quot;
        srcset=&quot;/static/53a9fd897b341a879f4cc8d8fe250c40/8ff5a/reactivex_xppuk4.png 240w,
/static/53a9fd897b341a879f4cc8d8fe250c40/e85cb/reactivex_xppuk4.png 480w,
/static/53a9fd897b341a879f4cc8d8fe250c40/0b533/reactivex_xppuk4.png 500w&quot;
        sizes=&quot;(max-width: 500px) 100vw, 500px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So, you have heard about &lt;a href=&quot;https://github.com/ReactiveX/RxSwift&quot;&gt;RxSwift&lt;/a&gt;. You see it ever so frequently in the wild. But whenever you try to wrap your head around it, it hurts. Here’s what the Github page says about RxSwift:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rx is a &lt;a href=&quot;https://www.youtube.com/watch?v=looJcaeboBY&amp;#x26;feature=youtu.be&quot;&gt;generic abstraction of computation&lt;/a&gt; expressed through Observable&lt;Element&gt; interface.
This is a Swift version of Rx.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So great, you go and start watching that video. It’s great, it is going to change programming for ever, but how do I use it. Let’s try to break it down. RxSwift is an implementation of &lt;a href=&quot;https://reactivex.io/&quot;&gt;ReactiveX&lt;/a&gt;. In the most simple terms, the ReactiveX Observable model allows you to treat streams of asynchronous events with the same sort of simple, composable operations that you use for collections of data items like arrays. No more tangled webs of callbacks.&lt;/p&gt;
&lt;p&gt;When building a frontend application, most of your tasks involve reacting to user interactions and doing something in response to them. It’s a great use case for RxSwift. Let’s take the example of a simple log in flow. Here are the events that you usually need to take care of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make a backend call to authenticate the user when he clicks login.&lt;/li&gt;
&lt;li&gt;On success, get user’s info from the backend.&lt;/li&gt;
&lt;li&gt;Handle errors and show messages on UI.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;APIProvider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Login&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;emailTextField&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trimmedText&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; passwordTextField&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;trimmedText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flatMapLatest&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; token &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; APIProvider&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;UserAccount&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; event &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    switch event &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    case &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Next&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;let user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
        log&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Login success: \(user.user.email)&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;loginDidFinishWithUser&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    case &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;let error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;loginDidFailWithError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;error&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    default&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addDisposableTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;disposeBag&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s break this up.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.Login&lt;/code&gt; is the actual call to the backend to authenticate our user. You could use any implementation that you prefer (I have used &lt;a href=&quot;https://github.com/Moya/Moya&quot;&gt;Moya&lt;/a&gt; that plays really nice with RxSwift) and returns an &lt;code class=&quot;language-text&quot;&gt;Observable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the login succeeds, it calls &lt;a href=&quot;https://reactivex.io/documentation/operators/flatmap.html&quot;&gt;flatMap&lt;/a&gt; with an item of the observable. flatMap returns another observable which could then be subscribed and observed again using chaining. This is where we make another request to the backend for the UserAccount if our login was successful.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Finally, with &lt;code class=&quot;language-text&quot;&gt;.subscribe&lt;/code&gt;, we start listening to the events from this Observable chain. The event could be &lt;code class=&quot;language-text&quot;&gt;.Next&lt;/code&gt; when a new element is emitted by the Observable. This means that the request was successful. It could be &lt;code class=&quot;language-text&quot;&gt;.Error&lt;/code&gt; in case of an error and &lt;code class=&quot;language-text&quot;&gt;.Completed&lt;/code&gt; when the observable completes.&lt;/p&gt;
&lt;p&gt;Let’s assume we want to consider failure status codes as &lt;code class=&quot;language-text&quot;&gt;.Error&lt;/code&gt; events on the observable. This becomes really easy with RxSwift. All we need is a &lt;a href=&quot;https://github.com/Moya/Moya/blob/master/Source/RxSwift/Observable%2BMoya.swift#L26&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;filterSuccessfulStatusAndRedirectCodes&lt;/code&gt;&lt;/a&gt; from Moya in the chain after our request. If you want to map the response into Swift objects, it’s got you covered there as well. Just use &lt;code class=&quot;language-text&quot;&gt;.mapObject(Class)&lt;/code&gt; from &lt;a href=&quot;https://github.com/ivanbruel/Moya-ObjectMapper&quot;&gt;Moya-ObjectMapper&lt;/a&gt; in the chain. You see how easy it was to make changes later by just adding things in the Observable chain?&lt;/p&gt;
&lt;p&gt;This is a very simple example of how to manage simple network calls in your application with RxSwift. It requires a bit of getting used to, but it’s well worth the effort. It helps write maintainable code that is easy to read or refactor at a later stage. If at any point, we want to add another call to the chain, we would simply need to add another &lt;code class=&quot;language-text&quot;&gt;flatMap&lt;/code&gt; operator in the Observable chain.&lt;/p&gt;
&lt;p&gt;This is supposed to be a very simple primer to RxSwift and in no way even close to the covering the myriad of &lt;a href=&quot;https://reactivex.io/documentation/operators.html&quot;&gt;operators&lt;/a&gt; available at your convenience.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why you should start using RxJava on Android]]></title><link>https://pulkitgoyal.in/why-you-should-start-using-rxjava-on-android</link><guid isPermaLink="false">https://pulkitgoyal.in/why-you-should-start-using-rxjava-on-android</guid><pubDate>Fri, 24 Jun 2016 16:07:15 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/53a9fd897b341a879f4cc8d8fe250c40/0b533/reactivex_xppuk4.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 500px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAKCAYAAAC0VX7mAAAACXBIWXMAAAsSAAALEgHS3X78AAABQUlEQVQoz2O4JzyBAQTeik1gOCXQz7iXtx/M3wWlyQL/FScylDP2MYHZ2lMZrwpNZwSxuRnZyTBMdRKc/UNiIjcWJSCLGJEwDKDzIaCIoRcsuIG7v+oQX/+3O5KTdn+XnC4LEpNmEubB4Q50g1lQZPcJ9Ysu4ez/OputL++NVH/xOu55EUBhK6DT8oG0HRCbA7ElEFsAcRQQ2wOxDhA7AHEsSC2KRUu5J7A/E5tw4L/MRDNdhjredqbpTQwMHGZAqSQgzoEaUg7EnkAcBMQ+QJwJxClADLLcBm7gS7EJkMiQnqD5Q3LCkstCExYv5eh3A4tJ/WeAeocdGpZsUD4z1ABWtHCGgNfiE+Cc/95Twew1XFMYyUoyQFeB6e+SExj/SU2EBAHHRLCrBRh5yUuH3yUmQJPNBIaP4hBD/0lOJMssAPDDTyOIJB58AAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;ReactiveX&quot;
        title=&quot;&quot;
        src=&quot;/static/53a9fd897b341a879f4cc8d8fe250c40/0b533/reactivex_xppuk4.png&quot;
        srcset=&quot;/static/53a9fd897b341a879f4cc8d8fe250c40/8ff5a/reactivex_xppuk4.png 240w,
/static/53a9fd897b341a879f4cc8d8fe250c40/e85cb/reactivex_xppuk4.png 480w,
/static/53a9fd897b341a879f4cc8d8fe250c40/0b533/reactivex_xppuk4.png 500w&quot;
        sizes=&quot;(max-width: 500px) 100vw, 500px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;So, you have heard about &lt;a href=&quot;https://github.com/ReactiveX/RxJava&quot;&gt;RxJava&lt;/a&gt;. You see it ever so frequently in the wild. But whenever you try to wrap your head around it, it hurts. Here’s what the Github page says about RxJava:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RxJava is a Java VM implementation of Reactive Extensions: a library for composing asynchronous and event-based programs by using observable sequences.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It extends the observer pattern to support sequences of data/events and adds operators that allow you to compose sequences together declaratively while abstracting away concerns about things like low-level threading, synchronization, thread-safety and concurrent data structures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That’s a mouthful. Let’s try to break it down. RxJava is an implementation of &lt;a href=&quot;https://reactivex.io/&quot;&gt;ReactiveX&lt;/a&gt;. In the most simple terms, the ReactiveX Observable model allows you to treat streams of asynchronous events with the same sort of simple, composable operations that you use for collections of data items like arrays. No more tangled webs of callbacks.&lt;/p&gt;
&lt;p&gt;When building a frontend application, most of your tasks involve reacting to user interactions and doing something in response to them. It’s a perfect use case for RxJava. Let’s take the example of a simple log in flow. Here are the events that you usually need to take care of:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make a backend call to authenticate the user when he clicks login.&lt;/li&gt;
&lt;li&gt;On success, get user’s info from the backend.&lt;/li&gt;
&lt;li&gt;Handle errors and show messages on UI.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;BackendService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;login&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;email&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; password&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribeOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Schedulers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;AndroidSchedulers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mainThread&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isSuccess&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token label symbol&quot;&gt;@Func1&lt;/span&gt; BackendService&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;userAccount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribeOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Schedulers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;handleError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;error&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Response&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;User&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Failed to get access token&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribeOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Schedulers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;io&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;observeOn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;AndroidSchedulers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;mainThread&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; response &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isSuccess&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;onUserLoginSuccess&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; device&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;handleError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;response&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; throwable &lt;span class=&quot;token operator&quot;&gt;-&gt;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;handleError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s break this up.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;.login&lt;/code&gt; makes the actual call to the backend to authenticate our user. You could use any implementation that you prefer (I have used &lt;a href=&quot;https://square.github.io/retrofit/&quot;&gt;Retrofit&lt;/a&gt; that plays really nice with RxJava) that returns an &lt;code class=&quot;language-text&quot;&gt;Observable&lt;/code&gt;. The implementation itself doesn’t need to worry about the thread it should perform the task on.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reactivex.io/documentation/operators/subscribeon.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;.subscribeOn&lt;/code&gt;&lt;/a&gt; instructs the observable to perform the task on a &lt;a href=&quot;https://reactivex.io/RxJava/javadoc/rx/schedulers/Schedulers.html#io()&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;IO&lt;/code&gt;&lt;/a&gt; thread that performs the task in the background.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reactivex.io/documentation/operators/observeon.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;.observeOn&lt;/code&gt;&lt;/a&gt; instructs which thread the &lt;code class=&quot;language-text&quot;&gt;Observer&lt;/code&gt; will be observed upon. This is so that we can perform the UI tasks on the main thread.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If the login succeeds, it calls &lt;a href=&quot;https://reactivex.io/documentation/operators/flatmap.html&quot;&gt;flatMap&lt;/a&gt; with an item of the observable. flatMap returns another observable which could then be subscribed and observed again using chaining. This is where we make another request to the backend if our login was successful.&lt;/p&gt;
&lt;p&gt;Finally, with &lt;code class=&quot;language-text&quot;&gt;.subscribe&lt;/code&gt;, we start listening to the results from this Observable chain. The first argument to subscribe is invoked for each successful result of the Observable. If the Observable fails with an error, the second function is called instead with an &lt;code class=&quot;language-text&quot;&gt;Exception&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Let’s assume we did some changes to the UI when the login failed. Now we would like to clear UI errors when text fields are edited. RxJava makes it very simple (with &lt;a href=&quot;https://github.com/JakeWharton/RxBinding&quot;&gt;RxBinding&lt;/a&gt; that converts UI interaction into RxJava Observables):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;merge&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;emailEditText&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;textChanges&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; passwordEditText&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;textChanges&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;updateButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Progress&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;NORMAL&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We simply get the &lt;code class=&quot;language-text&quot;&gt;.textChanges&lt;/code&gt; Observables for the edit texts, merge them into one Observable (which means that the subscribe will be called for events from either of these two Observables) and then reset the UI inside subscribe.&lt;/p&gt;
&lt;p&gt;This is a very simple example of how to manage simple UI flows in your application with RxJava. It requires a bit of getting used to, but it’s well worth the effort. It helps write maintainable code that is easy to read or refactor at a later stage. If at any point, we want to add another call to the chain, we would simply need to add another &lt;code class=&quot;language-text&quot;&gt;flatMap&lt;/code&gt; operator in the Observable chain.&lt;/p&gt;
&lt;p&gt;This is supposed to be a very simple primer to RxJava and in no way even close to the covering the myriad of &lt;a href=&quot;https://reactivex.io/documentation/operators.html&quot;&gt;operators&lt;/a&gt; available at your convenience.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Swift constructs for Kotlin]]></title><link>https://pulkitgoyal.in/swift-constructs-for-kotlin</link><guid isPermaLink="false">https://pulkitgoyal.in/swift-constructs-for-kotlin</guid><pubDate>Fri, 13 May 2016 15:19:45 GMT</pubDate><content:encoded>&lt;p&gt;If you have used Swift for iOS development, chances are that you really miss its flexibility when developing for Android with Java. &lt;a href=&quot;https://kotlinlang.org/&quot;&gt;Kotlin&lt;/a&gt; brings all the Swift goodness to Java that combines OO and functional features and is focused on interoperability, safety, clarity and tooling support. Let’s see a few Swift constructs and their equivalent on Kotlin:&lt;/p&gt;
&lt;h3&gt;Unwrapping&lt;/h3&gt;
&lt;p&gt;In Swift, we unwrap with &lt;code class=&quot;language-text&quot;&gt;guard let&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; unwrapped &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; wrapped &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In Kotlin, we use the elvis operator&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; unwrapped &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; wrapped &lt;span class=&quot;token operator&quot;&gt;?:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Blocks and Lambdas&lt;/h3&gt;
&lt;p&gt;In Swift, we can reference parameters without specifying the complete signature using &lt;code class=&quot;language-text&quot;&gt;$0, $1, …&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; doubleNumbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; numbers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; $&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In Kotlin, we use &lt;code class=&quot;language-text&quot;&gt;it&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; doubleNumbers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; numbers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; it &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Named Parameters&lt;/h3&gt;
&lt;p&gt;Swift uses named parameters&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token function&quot;&gt;addNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; with&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Call with named parameters&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; with&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; with
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Kotlin has named parameters too&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token function&quot;&gt;addNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; with &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Call with named parameters&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addNumber&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;number&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Int&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; with&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Int&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Int &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; with&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Computed Properties&lt;/h3&gt;
&lt;p&gt;We define computed properties with (optional) getter in Swift&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;firstName&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token delimiter variable&quot;&gt;\(&lt;/span&gt;lastName&lt;span class=&quot;token delimiter variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Computed properties defined with get in Kotlin&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String
  &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation variable&quot;&gt;$firstName&lt;/span&gt; &lt;span class=&quot;token interpolation variable&quot;&gt;$lastName&lt;/span&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt; Or even smaller with &lt;code class=&quot;language-text&quot;&gt;=&lt;/code&gt; syntax&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;kotlin&quot;&gt;&lt;pre class=&quot;language-kotlin&quot;&gt;&lt;code class=&quot;language-kotlin&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;val&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String
  &lt;span class=&quot;token keyword&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&lt;span class=&quot;token interpolation variable&quot;&gt;$firstName&lt;/span&gt; &lt;span class=&quot;token interpolation variable&quot;&gt;$lastName&lt;/span&gt;&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;String templates&lt;/h3&gt;
&lt;p&gt;We write string templates like &lt;code class=&quot;language-text&quot;&gt;&amp;quot;\(firstName) \(lastName)&amp;quot;&lt;/code&gt; in Swift and &lt;code class=&quot;language-text&quot;&gt;&amp;quot;$firstName $lastName&amp;quot;&lt;/code&gt; in Kotlin&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Add a circle around UIImage]]></title><link>https://pulkitgoyal.in/add-a-circle-around-uiimage</link><guid isPermaLink="false">https://pulkitgoyal.in/add-a-circle-around-uiimage</guid><pubDate>Sun, 24 Jan 2016 09:00:30 GMT</pubDate><content:encoded>&lt;p&gt;For an app I worked on recently, we had the need to add a circle around an &lt;code class=&quot;language-text&quot;&gt;UIImage&lt;/code&gt;. When using a &lt;code class=&quot;language-text&quot;&gt;UIImageView&lt;/code&gt;, it is pretty straightforward to add a border to the image view. Unfortunately, we were using a library with no control over the &lt;code class=&quot;language-text&quot;&gt;UIImageView&lt;/code&gt; for a particular feature within  the app and had to switch to manually adding the border in the UIImage before passing it over to the library. Here’s a category on &lt;code class=&quot;language-text&quot;&gt;UIImage&lt;/code&gt; to do so. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;@implementation UIImage (PGHelpers)

- (UIImage *)borderedImageWithPadding:(int)padding {
    // Draw image
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.size.width + padding, self.size.height + padding), NO, [UIScreen mainScreen].scale);
    CGContextRef context = UIGraphicsGetCurrentContext();
    [self drawInRect:CGRectMake(padding / 2, padding / 2, self.size.width, self.size.height)];

    // Add border
    UIBezierPath *bezier = [UIBezierPath bezierPath];
    [bezier setLineWidth:4.f];
    [bezier setLineJoinStyle:kCGLineJoinRound];
    [bezier addArcWithCenter:CGPointMake(self.size.width / 2 + padding / 2, self.size.height / 2 + padding / 2) radius:self.size.height / 2 + padding / 2 - 2 startAngle:0 endAngle:M_PI clockwise:NO];
    [bezier addArcWithCenter:CGPointMake(self.size.width / 2 + padding / 2, self.size.height / 2 + padding / 2) radius:self.size.height / 2 + padding / 2 - 2 startAngle:M_PI endAngle:2 * M_PI clockwise:NO];
    CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor);
    [bezier stroke];

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Create UIImage with text]]></title><link>https://pulkitgoyal.in/create-uiimage-with-user-initials</link><guid isPermaLink="false">https://pulkitgoyal.in/create-uiimage-with-user-initials</guid><pubDate>Sat, 19 Dec 2015 12:53:58 GMT</pubDate><content:encoded>&lt;p&gt;While making an application, showing user’s image is a very common use case. Gone were the days when we used to show anonymous image in case a person’s profile image or display image is not present. We can easily show a person’s initials to make it easier to identify the person. Here’s a simple category to generate an UIImage with centered text overlayed on top of it.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objectivec&quot;&gt;&lt;pre class=&quot;language-objectivec&quot;&gt;&lt;code class=&quot;language-objectivec&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@implementation&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PGHelpers&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UIImage &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;imageWithCenteredText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;NSString &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;text withfont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UIFont &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;font &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    CGSize size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;text sizeWithAttributes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;NSFontAttributeName &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; imageWithText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;text atPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;CGPointMake&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; withFont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;font&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UIImage &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;imageWithText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;NSString &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;text atPoint&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;CGPoint&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;point withFont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;UIFont &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;font &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;UIGraphicsBeginImageContextWithOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; YES&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt; drawInRect&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;CGRectMake&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    CGRect rect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CGRectMake&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;point&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; point&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;UIColor whiteColor&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; set&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    NSDictionary &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;att &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;NSFontAttributeName &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; font&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; NSForegroundColorAttributeName &lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;UIColor whiteColor&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;text drawInRect&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;rect withAttributes&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;att&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    UIImage &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;newImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;UIGraphicsGetImageFromCurrentImageContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;UIGraphicsEndImageContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; newImage&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;@end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This can be chained with other methods (e.g. from &lt;a href=&quot;https://github.com/vilanovi/UIImage-Additions&quot;&gt;UIImage-Additions&lt;/a&gt;, &lt;a href=&quot;https://github.com/mustangostang/UIImage-ResizeMagick&quot;&gt;UIImage-ResizeMagick&lt;/a&gt; etc.) to create compelling profile images with advance blurring effects etc. Here’s an example that resizes the image to &lt;code class=&quot;language-text&quot;&gt;size x size&lt;/code&gt;, blurs it, adds the user initials in the center, crops it to a circle and finally adds a border around it: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objectivec&quot;&gt;&lt;pre class=&quot;language-objectivec&quot;&gt;&lt;code class=&quot;language-objectivec&quot;&gt;UIImage &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;blurredImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;image resizedImageByMagick&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;NSString stringWithFormat&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;@&quot;%dx%d#&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; blurredImageWithRadius&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt; iterations&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; tintColor&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;UIColor clearColor&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;blurredImage imageWithCenteredText&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;profile&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;avatarInitials withfont&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;UIFont fontWithName&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;kPGFontNameAvenirNextCondensedRegular size&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; add_imageWithRoundedBounds&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; borderedImageWithPadding&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Resizing images picked from UIImagePickerController]]></title><link>https://pulkitgoyal.in/resizing-images-picked-from-uiimagepickercontroller</link><guid isPermaLink="false">https://pulkitgoyal.in/resizing-images-picked-from-uiimagepickercontroller</guid><pubDate>Sun, 29 Nov 2015 15:46:10 GMT</pubDate><content:encoded>&lt;p&gt;There’s already a lot of stuff about image resizing on iOS already available on the web with each discussing about potential pros and cons of the technique. There is also a &lt;a href=&quot;https://nshipster.com/image-resizing/&quot;&gt;good post on NSHipster&lt;/a&gt; summarizing some of the best available image resizing techniques.&lt;/p&gt;
&lt;p&gt;With iOS 8, Apple has given us &lt;a href=&quot;https://developer.apple.com/library/prerelease/ios//documentation/Photos/Reference/Photos_Framework/index.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PhotoKit&lt;/code&gt;&lt;/a&gt;, a modern framework for managing photos without diving into the low level details and more performant than AssetsLibrary. Let’s see how we can resize a simple image selected using the &lt;code class=&quot;language-text&quot;&gt;UIImagePickerController&lt;/code&gt; using PhotoKit.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;swift&quot;&gt;&lt;pre class=&quot;language-swift&quot;&gt;&lt;code class=&quot;language-swift&quot;&gt;imagePickerController&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bk_didFinishPickingMediaBlock &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;controller imagePickerController&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UIImagePickerController&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dictionary&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;NSObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;AnyObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
    imagePickerController&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dismissViewControllerAnimated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; completion&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; assetURL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dictionary&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;UIImagePickerControllerReferenceURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;NSURL&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; image &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dictionary&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;UIImagePickerControllerOriginalImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// TODO Image taken from the camera. Resize using one of the techniques discussed on https://nshipster.com/image-resizing/&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Fetch Photos Asset and resize image&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; fetchResult &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;PHAsset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetchAssetsWithALAssetURLs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;assetURL&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; options &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;PHImageRequestOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;synchronous &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resizeMode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;Fast&lt;/span&gt;
    options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deliveryMode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;HighQualityFormat&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;guard&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; asset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fetchResult&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;firstObject &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;PHAsset&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; image &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dictionary&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;UIImagePickerControllerOriginalImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;UIImage&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;// TODO Cannot find the associated PhotoKit asset. Resize using one of the techniques discussed on https://nshipster.com/image-resizing/&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Request resized image&lt;/span&gt;
    &lt;span class=&quot;token builtin&quot;&gt;PHImageManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;requestImageForAsset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;asset&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; targetSize&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;CGSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; contentMode&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token builtin&quot;&gt;AspectFit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resultHandler&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token builtin&quot;&gt;Void&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// image is the resized image&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code is pretty straightforward. We fetch the &lt;a href=&quot;https://developer.apple.com/library/prerelease/ios//documentation/Photos/Reference/PHAsset_Class/index.html#//apple_ref/occ/cl/PHAsset&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHAsset&lt;/code&gt;&lt;/a&gt; from the asset url of the image and then use the &lt;a href=&quot;https://developer.apple.com/library/prerelease/ios//documentation/Photos/Reference/PHImageManager_Class/index.html#//apple_ref/occ/cl/PHImageManager&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PHImageManager&lt;/code&gt;&lt;/a&gt; to get the resized image. There are a few options to control the scaling mode.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;deliveryMode&lt;/code&gt; : Controls the requested image quality and delivery priority.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Opportunistic&lt;/code&gt;: Photos automatically provides one or more results in order to balance image quality and responsiveness. The resultHandler block more than once with different quality images as they become available.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;HighQualityFormat&lt;/code&gt;: Photos provides only the highest-quality image available, regardless of how much time it takes to load.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;FastFormat&lt;/code&gt;:  Photos provides only a fast-loading image, possibly sacrificing image quality.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;resizeMode&lt;/code&gt;: A mode that specifies how to resize the requested image.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;None&lt;/code&gt;: Photos does not resize the image asset.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Fast&lt;/code&gt;: Photos efficiently resizes the image to a size similar to, or slightly larger than, the target size.&lt;/li&gt;
&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Exact&lt;/code&gt;: Photos resizes the image to match the target size exactly.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Show avatar on both sides for Atlas Conversation View Controller (Layer Chat)]]></title><link>https://pulkitgoyal.in/show-avatar-on-both-sides-for-atlas-conversation-view-controller-layer-chat</link><guid isPermaLink="false">https://pulkitgoyal.in/show-avatar-on-both-sides-for-atlas-conversation-view-controller-layer-chat</guid><pubDate>Sat, 11 Jul 2015 09:27:50 GMT</pubDate><content:encoded>&lt;p&gt;Atlas is a fully featured, high performance, 100% customizable UI kit, built by Layer to power communications interfaces in any app. If you want to learn how to integrate chat in your iOS app, take a look at &lt;a href=&quot;https://pulkitgoyal.in/getting-started-with-layer-to-include-chat-in-ios-apps/&quot;&gt;Implementing Chat/Messaging in iOS apps with Layer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Atlas does provide quick customization of some common options. But it also assumes some pretty rigid defaults which are not easy to change unless you are willing to spend some time digging through it’s codebase. One such thing is when you want to show avatar on both sides of the conversation. By default, the &lt;a href=&quot;https://github.com/layerhq/Atlas-iOS/blob/master/Code/Controllers/ATLConversationViewController.h&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ÀTLConversationViewController&lt;/code&gt;&lt;/a&gt; only allows showing avatar on the incoming messages.&lt;/p&gt;
&lt;h2&gt;Add avatars on Outgoing Messages&lt;/h2&gt;
&lt;p&gt;To add avatars on outgoing messages, we need to subclass the &lt;a href=&quot;https://github.com/layerhq/Atlas-iOS/blob/4404dc8ac566c26fc8f3bc298f93a31a4b28aa36/Code/Views/ATLMessageCollectionViewCell.h&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ATLMessageCollectionViewCell&lt;/code&gt;&lt;/a&gt; and override its methods to make the avatar visible. There are three steps here:&lt;/p&gt;
&lt;h3&gt;Update the constraints&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;@implementation PGOutgoingMessageCollectionViewCell

NSString *const PGOutgoingMessageCellIdentifier = @&amp;quot;PGOutgoingMessageCellIdentifier&amp;quot;;
CGFloat const PGAvatarPGAvatarImageRightPadding = 12.0f;
CGFloat const PGAvatarImageLeftPadding = 7.0f;

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self lyr_incommingCommonInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self lyr_incommingCommonInit];
    }
    return self;
}

- (void)lyr_incommingCommonInit {
    [self configureConstraintsForIncomingMessage];
}

- (void)configureConstraintsForIncomingMessage {
    [self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.contentView.mas_right).with.offset(-PGAvatarImageRightPadding);
        make.bottom.equalTo(self.avatarImageView.mas_bottom);
        make.height.equalTo(@35);
        make.width.equalTo(@35);
    }];
    self.bubbleWithAvatarRightConstraint = [NSLayoutConstraint constraintWithItem:self.bubbleView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.avatarImageView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:-PGAvatarImageLeftPadding];
    [self.contentView addConstraint:self.bubbleWithAvatarRightConstraint];
    self.bubbleWithoutAvatarRightConstraint = [NSLayoutConstraint constraintWithItem:self.bubbleView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeRight multiplier:1.0 constant:ATLMessageCellHorizontalMargin];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.avatarImageView.layer.cornerRadius = CGRectGetHeight(self.avatarImageView.frame) / 2;
}
@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Override display logic&lt;/h3&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)shouldDisplayAvatarItem:(BOOL)shouldDisplayAvatarItem {
    NSArray *constraints = [self.contentView constraints];
    if (shouldDisplayAvatarItem) {
        if ([constraints containsObject:self.bubbleWithAvatarRightConstraint]) return;
        [self.contentView removeConstraint:self.bubbleWithoutAvatarRightConstraint];
        [self.contentView addConstraint:self.bubbleWithAvatarRightConstraint];
    } else {
        if ([constraints containsObject:self.bubbleWithoutAvatarRightConstraint]) return;
        [self.contentView removeConstraint:self.bubbleWithAvatarRightConstraint];
        [self.contentView addConstraint:self.bubbleWithoutAvatarRightConstraint];
    }
    [self setNeedsUpdateConstraints];
}

- (void)updateWithSender:(id &amp;lt;ATLParticipant&amp;gt;)sender {
    if (sender) {
        self.avatarImageView.hidden = NO;
        self.avatarImageView.avatarItem = sender;
    } else {
        self.avatarImageView.hidden = YES;
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Register our class for outgoing messages&lt;/h3&gt;
&lt;p&gt;In your &lt;code class=&quot;language-text&quot;&gt;ATLConversationViewController&lt;/code&gt; subclass, do the following somewhere in &lt;code class=&quot;language-text&quot;&gt;viewDidLoad&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)viewDidLoad {
    [self registerClass:[PGOutgoingMessageCollectionViewCell class] forMessageCellWithReuseIdentifier:PGOutgoingMessageCellIdentifier];
}

- (NSString *)conversationViewController:(ATLConversationViewController *)viewController reuseIdentifierForMessage:(LYRMessage *)message {
    if ([message.sentByUserID isEqualToString:self.layerClient.authenticatedUserID]) {
        return PGOutgoingMessageCellIdentifier;
    }
    return ATLIncomingMessageCellIdentifier;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Need help setting this up or just want to chat? Shoot me an email at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Add Click Handler to Avatars on Atlas (Layer Chat)]]></title><link>https://pulkitgoyal.in/add-click-handler-to-avatars-on-atlas-layer-chat</link><guid isPermaLink="false">https://pulkitgoyal.in/add-click-handler-to-avatars-on-atlas-layer-chat</guid><pubDate>Sun, 21 Jun 2015 13:50:59 GMT</pubDate><content:encoded>&lt;p&gt;Atlas is a fully featured, high performance, 100% customizable UI kit, built by Layer to power communications interfaces in any app. If you want to learn how to integrate chat in your iOS app, take a look at &lt;a href=&quot;https://pulkitgoyal.in/getting-started-with-layer-to-include-chat-in-ios-apps/&quot;&gt;Implementing Chat/Messaging in iOS apps with Layer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the previous post, I talked about subclassing &lt;code class=&quot;language-text&quot;&gt;ATLMessageCollectionViewCell&lt;/code&gt; to display avatars on both sides in a conversation. Let’s take that a step further and see how we can handle tap on avatars in a conversation. We will subclass the same class this time, but for the incoming messages rather than the outgoing ones.&lt;/p&gt;
&lt;h2&gt;Create a cell for incoming messages&lt;/h2&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;@interface PGIncomingMessageCollectionViewCell ()
@property(nonatomic, strong) UITapGestureRecognizer *avatarTapGestureRecognizer;
@end

@implementation PGIncomingMessageCollectionViewCell

NSString *const PGIncomingMessageCellIdentifier = @&amp;quot;PGIncomingMessageCellIdentifier&amp;quot;;

- (void)lyr_incommingCommonInit {
    [super lyr_incommingCommonInit];

    self.avatarTapGestureRecognizer = [[UITapGestureRecognizer alloc] bk_initWithHandler:^(UIGestureRecognizer *sender, UIGestureRecognizerState state, CGPoint location) {
        // TODO Handle a tap on the avatar item
    }];
    [self.avatarImageView addGestureRecognizer:self.avatarTapGestureRecognizer];
    self.avatarImageView.userInteractionEnabled = YES;

    [self.avatarImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.height.equalTo(@35);
        make.width.equalTo(@35);
    }];
}

- (void)layoutSubviews {
    [super layoutSubviews];
    self.avatarImageView.layer.cornerRadius = CGRectGetHeight(self.avatarImageView.frame) / 2;
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h2&gt;Register our cell for incoming messages&lt;/h2&gt;
&lt;p&gt;In your &lt;code class=&quot;language-text&quot;&gt;ATLConversationViewController&lt;/code&gt; subclass, do the following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)viewDidLoad {
    [self registerClass:[PGIncomingMessageCollectionViewCell class] forMessageCellWithReuseIdentifier:PGIncomingMessageCellIdentifier];
}

- (NSString *)conversationViewController:(ATLConversationViewController *)viewController reuseIdentifierForMessage:(LYRMessage *)message {
    if ([message.sentByUserID isEqualToString:self.layerClient.authenticatedUserID]) {
        return PGOutgoingMessageCellIdentifier;
    }
    return PGIncomingMessageCellIdentifier;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Need help setting this up or just want to chat? Shoot me an email at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Open full image in conversation controller with Atlas (Layer Chat)]]></title><link>https://pulkitgoyal.in/enlarge-image-in-conversation-controller-with-atlas-layer-chat</link><guid isPermaLink="false">https://pulkitgoyal.in/enlarge-image-in-conversation-controller-with-atlas-layer-chat</guid><pubDate>Wed, 13 May 2015 19:45:36 GMT</pubDate><content:encoded>&lt;p&gt;Atlas is a fully featured, high performance, 100% customizable UI kit, built by Layer to power communications interfaces in any app. If you want to learn how to integrate chat in your iOS app, take a look at &lt;a href=&quot;https://pulkitgoyal.in/getting-started-with-layer-to-include-chat-in-ios-apps/&quot;&gt;Implementing Chat/Messaging in iOS apps with Layer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;By default, Atlas doesn’t open full resolution images when a message with an image is clicked. This tutorial explains how to configure Atlas to show the full image when on message click.&lt;/p&gt;
&lt;p&gt;Atlas provides a &lt;code class=&quot;language-text&quot;&gt;conversationViewController:didSelectMessage&lt;/code&gt; method which the class implementing &lt;code class=&quot;language-text&quot;&gt;ATLConversationViewControllerDelegate&lt;/code&gt; can implement to perform actions when a message is clicked. We will check whether the message contains an image and present an image view controller if it does.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)conversationViewController:(ATLConversationViewController *)viewController didSelectMessage:(LYRMessage *)message {
    LYRMessagePart *JPEGMessagePart = ATLMessagePartForMIMEType(message, ATLMIMETypeImageJPEG);
    if (JPEGMessagePart) {
        [self presentImageViewControllerWithMessage:message];
        return;
    }
    LYRMessagePart *PNGMessagePart = ATLMessagePartForMIMEType(message, ATLMIMETypeImagePNG);
    if (PNGMessagePart) {
        [self presentImageViewControllerWithMessage:message];
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In order to show the image, we first need to load the image from Layer. Create a method &lt;code class=&quot;language-text&quot;&gt;loadLowResImageForMessage:&lt;/code&gt; that loads the low resolution image for a message.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (UIImage *)loadLowResImageForMessage:(LYRMessage *)message {
    LYRMessagePart *lowResImagePart = ATLMessagePartForMIMEType(message, ATLMIMETypeImageJPEGPreview);
    LYRMessagePart *imageInfoPart = ATLMessagePartForMIMEType(message, ATLMIMETypeImageSize);

    if (!lowResImagePart) {
        // Default back to image/jpeg MIMEType
        lowResImagePart = ATLMessagePartForMIMEType(message, ATLMIMETypeImageJPEG);
    }

    // Retrieve low-res image from message part
    if (!(lowResImagePart.transferStatus == LYRContentTransferReadyForDownload || lowResImagePart.transferStatus == LYRContentTransferDownloading)) {
        if (lowResImagePart.fileURL) {
            return [UIImage imageWithContentsOfFile:lowResImagePart.fileURL.path];
        } else {
            return [UIImage imageWithData:lowResImagePart.data];
        }
    }
    return nil;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;To present the image in a new view controller, we will use the &lt;a href=&quot;https://github.com/jaredsinclair/JTSImageViewController&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;JTSImageViewController&lt;/code&gt;&lt;/a&gt; library to simplify our work. Include the following in your &lt;code class=&quot;language-text&quot;&gt;Podfile&lt;/code&gt; and do &lt;code class=&quot;language-text&quot;&gt;pod install&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;pod &amp;#39;JTSImageViewController&amp;#39;, &amp;#39;~&amp;gt; 1.4&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you are using some other library, modify the following method accordingly.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)presentImageViewControllerWithMessage:(LYRMessage *)message {
    // Create image info
    JTSImageInfo *imageInfo = [[JTSImageInfo alloc] init];
    imageInfo.image = [self loadLowResImageForMessage:message];

    // Setup view controller
    JTSImageViewController *imageViewer = [[JTSImageViewController alloc] initWithImageInfo:imageInfo mode:JTSImageViewControllerMode_Image backgroundStyle:JTSImageViewControllerBackgroundOption_Scaled message:message];

    // Present the view controller.
    [imageViewer showFromViewController:self transition:JTSImageViewControllerTransition_FromOffscreen];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;However, this just loads the low resolution image in the view controller. Let’s initialize the view controller with the low res image and load the high resolution image in the background and replace it when it’s available. Create a subclass of &lt;code class=&quot;language-text&quot;&gt;JTSImageViewController&lt;/code&gt; named &lt;code class=&quot;language-text&quot;&gt;PGConversationImageViewController&lt;/code&gt; and use that in the above method instead of &lt;code class=&quot;language-text&quot;&gt;JTSImageViewController&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;//
//  PGConversationImageViewController.h
//

#import &amp;quot;JTSImageViewController.h&amp;quot;

@interface PGConversationImageViewController : JTSImageViewController &amp;lt;LYRProgressDelegate&amp;gt;
@property(nonatomic, strong) LYRMessage *message;

- (id)initWithImageInfo:(JTSImageInfo *)info mode:(enum JTSImageViewControllerMode)mode backgroundStyle:(enum JTSImageViewControllerBackgroundOptions)style message:(LYRMessage *)message;
@end


//
//  PGConversationImageViewController.m
//

#import &amp;lt;LayerKit/LYRMessagePart.h&amp;gt;
#import &amp;lt;Atlas/Utilities/ATLMessagingUtilities.h&amp;gt;
#import &amp;quot;PGConversationImageViewController.h&amp;quot;

@interface PGConversationImageViewController ()
@property(nonatomic, strong) UIImage *fullResImage;
- (void)updateInterfaceWithImage:(UIImage *)image;
@end

@implementation PGConversationImageViewController
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self downloadFullResImageIfNeeded];
}

- (id)initWithImageInfo:(JTSImageInfo *)info mode:(enum JTSImageViewControllerMode)mode backgroundStyle:(enum JTSImageViewControllerBackgroundOptions)style message:(LYRMessage *)message {
    PGConversationImageViewController *_self = [self initWithImageInfo:self.imageInfo mode:mode backgroundStyle:style];
    if (_self) {
        _self.message = message;
    }
    return _self;
}

#pragma mark - Layer Image Downloads

- (void)loadFullResImages {
    LYRMessagePart *fullResImagePart = ATLMessagePartForMIMEType(self.message, ATLMIMETypeImageJPEG);
    if (!fullResImagePart) {
        fullResImagePart = ATLMessagePartForMIMEType(self.message, ATLMIMETypeImagePNG);
    }

    // Retrieve hi-res image from message part
    if (!(fullResImagePart.transferStatus == LYRContentTransferReadyForDownload || fullResImagePart.transferStatus == LYRContentTransferDownloading)) {
        if (fullResImagePart.fileURL) {
            self.fullResImage = [UIImage imageWithContentsOfFile:fullResImagePart.fileURL.path];
        } else {
            self.fullResImage = [UIImage imageWithData:fullResImagePart.data];
        }
        [self updateInterfaceWithImage:self.fullResImage];
    }
}

- (void)downloadFullResImageIfNeeded {
    LYRMessagePart *fullResImagePart = ATLMessagePartForMIMEType(self.message, ATLMIMETypeImageJPEG);
    if (!fullResImagePart) {
        fullResImagePart = ATLMessagePartForMIMEType(self.message, ATLMIMETypeImagePNG);
    }

    // Download hi-res image from the network
    if (fullResImagePart &amp;amp;&amp;amp; (fullResImagePart.transferStatus == LYRContentTransferReadyForDownload || fullResImagePart.transferStatus == LYRContentTransferDownloading)) {
        NSError *error;
        LYRProgress *downloadProgress = [fullResImagePart downloadContent:&amp;amp;error];
        if (!downloadProgress) {
            NSLog(@&amp;quot;Problem downloading full resolution photo - %@&amp;quot;, error);
            return;
        }
        downloadProgress.delegate = self;
    } else {
        [self loadFullResImages];
    }
}

#pragma mark - LYRProgress Delegate Implementation

- (void)progressDidChange:(LYRProgress *)progress {
    // Queue UI updates onto the main thread, since LYRProgress performs
    // delegate callbacks from a background thread.
    dispatch_async(dispatch_get_main_queue(), ^{
        BOOL progressCompleted = progress.fractionCompleted == 1.0f;
        // After transfer completes, remove self for delegation.
        if (progressCompleted) {
            progress.delegate = nil;
            self.title = @&amp;quot;Image Downloaded&amp;quot;;
            [self loadFullResImages];
        }
    });
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s how it should look now:&lt;/p&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/e4f6a1cae87578b1a49e47c281bf7c13/f816d/LayerChatImage_byvyup.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 461px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 197.08333333333334%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAnCAYAAAAPZ2gOAAAACXBIWXMAAAsSAAALEgHS3X78AAAIiklEQVRIx62WeVRU1x3HX/pP25geSTWtgKfaGgWUGXYBt7oUgdk3ZoYdhk1xAXeM2kaioMZihFFRcAE1AuISqUqM1Rw8sTVNjNbAgBIUZRlcEEEYZN673973BkRzWk/+6Dvnc+6de3+/7/vd++78fpdh6NNy52YJ3vAQwoFj2TeZoKXx+9O8FvPd38t8+3qeorfPxvX09Lzo7u629/f32+vrb9stlga71Wq1X7lyxV5TU2Nvamqy9/X12XkbajvEAPW1swM23Prq7GzmXsNNnX1gACzLcna7nfDwz5POTjx50gmbzYaOjg6B7p4ecBwHaoMhWx7qy/KraL5Tm8Q8sFxTP+vqRJ3FwtXV1REKaikNDQ0CFosFt2/fFqivrwc//yN4H7an+xla7twwMQOP7iSeP1uFkSOdWFdXV+Li4gIeZ2dngVf7Q79fZezYseSdd37FlpcdA563mxiusym58ng5Jk1yY5VKBQkPC4MknCccYbQfTluJRCIQ/srYUF+pVBJ3dw/24IH9wIvHSQz6rerysk8h8vLlVPpYIlXpIVUZoNQaYDQaoNPpBDGpVIqIiAgYDAbo9fqXbWxsLPH3D2APHTwADDxJYPC8Jaqi/Bg8RWJWpzcSmUINmVIDhUoDtVoNlUoFmUxGBWU0GpUwplZrBlHTlxqJt7cPW3LoINDTtoRB9/2FJysr4OkpstO3El7A4aSmy5IgNDT05fLmzw8VUKkcovwL9HoDEYu97IdLS8B1t37IkGfN6cOCRsIbq6ixw0kLjUZH0Q6iE9BqIwQxfiwyMop4eXkPC9I9jCg7dhQikZhzCKqooCMChZJuvmQujS6ERjkfoXwrCYFUFoI5c2fRbQjn7Qj1pUs+ALbrQQaD3tb4ivIyiMRilhdUKh1icrkcYh8XiLzfwx8mOuF9t/cwWeSKqcGuCJoxBm6TR9MPOQ5BQUGEPyHCR+l7mMDv4aIT9Ni4uYvt/H6olEoqGEEFlXDzcKYfyxmTPEZjite78PUfC5GvC7z9+TEnePl4gA9CLPZh9xcXUcGOJMbW0ZhSff40MtZ4sLuLZ5MNOSFIzZyG9GUyLF0xG4kpoUhbMhOmlD9iwaJQbNkZiPWbRVi0IhjpmSHQGP1IXHIAe6aqDLZHD0xMb9sPui8unkLqcmdu48cSYi5WYu2m6ZBHjkdMWjAiEicjKUOM3LxUFJZE40S1Asf/FoZN+RIUliYhNsWfRMS5sF9crER3WzP9pzy9rzlTVYn52rHctgIJ2VGgwOaPZyMtczKyd0iQXxxLhWJhPqjBsTMJ2HN4Kq5cNyJvrx7Zee9j5Qd/IhlZ89iLl8rR1UIF7Y/vas+ePQlphDu3ZJUfSV/lhSWrgrFs1Rzk7ffF5k9mInvLHOz/NBrLs+XYXiTHzgPzsDonCGs/8sSaDVJSsCeXvX79Mtoaa4Ulay9dPoOYFA8uO0dOcjfFYmVWNBZmhmJ9znQsX+OFkp1iVFVpqZAaOQXxOHomDrsOaZBfaKCrMZEly/7Cfnm5Bl2tdSamp6VZe7mmEmtzx3DrNs8le4tWYPsOI2JS3aDUTUFq2kRUHxajvHgidpWG4cNt05B/0Iivvy3AX6n40tWRJHmJlj1fXYWe9kYTY7Pe035+4QRMGeO4hSsCSdZHs7EuewZMaVMRMOu3CJr7Lr65NA67P5mAldkzkbN9GrYWqLG7OAkZK2ZQEkhMUgB76nQpPYYtJqb/4T3t+eoTiEqcwMkVYhIqCYYxIVjYt4wsb4QoxqDi6Dis/rM3Fq/2R0qmB5IW08iXemJBehgS04JJwKxfsOUVJXjR2eqI8MKFSsgiXTm53o3IVWKkLpqKDzbPQNYmH2zKm4q4NHckLPSGPtYDmphx0CeMhz7aEzFJ4TDEBJLIeCl78tRxGuFdGmHHXW315ycxTerCqeM9SFycL7bumIlF64MRs1SEPHMYFqzxpYJeUBg8EKL+PQxJIirmh7gFgdiYu45krlzFnv6sAr0dgmATFTxFDcdzWRu8yIqV0+kZ9MTSLB9EpUxBcrofCvZHYfG6GUhdLMacsAnQRU9EYqI3opLdoYt3J8aYGPbc+XPobm8w0QTbqi0rOwIfv8lcZJSK6A0yyBRhiI6R0eQpoYlWioXpidDoFdDqpJArwhEVLUd8nBJ6gxZ6o4xMmz6TLSkpBfuMfhT0tWmPHC6l+dCb0+sjiULBZ2IdFAotzXlaISdKpQqolHyOdPxW0jk5tVMoVDQ5RNHkIGb37S0Eeq28YKv26JFSPn1xQxnbkVyH0Wg0L/uvzvF93ocvAUVF+xxVT4iQFxR5cUMZe7hmvBmHoKOmFO3bSwWt/2/B9uE9HC4BjqX8VF4TFPawt4UKlgiCfMbmi89PFRuqerRIOfaQFyTP7gkR0mLNxccnEKMxkq9kr8GP/a9x3icwMIgtpiVAODb2J43a0pJDoDc7btSoUcTJyQk/5tejRgn8t7nRo0cT6ssWFu7BwNP7Jqbh62pNvaUWBeZdXIG5gBSYzRimAOZdu7Bt6xZs3ZKL1+ccmM1msjM/n7XU1aLxRo2Jqf32iq6vrxcsRziW48gg/H1RuJk+7XyC1vv38KijHf22XnCEQJh3INjTMXZg4AUsN64lMzVVh+d1dT6G9eGjgbb2dpbCDbZse0cHe6/pDmu1trOPHj9m21qa2XarlR2aH8L68OGL5z3duHrhhIZxZpif19+8VstH0/O8F8/7+ig2/oostDZbH/gXNjf9gK6uLvTa+oXxIXgf/mm49c39TJnHSOGeXbp9zcTrX1081VB7o+523b/rGr7/zvKS2huWW9f/abn5r6tCv56OvUIdz/Wrl84dM28UC2JfVh15ixl8fscwvwz5DTPCl2He9meYEQEUL9qfQlu/nzEjRLQNHBynvB1MW3faDvn/4+Jnb/0HiwBUMh6AlysAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;LayerChatImage byvyup&quot;
        title=&quot;&quot;
        src=&quot;/static/e4f6a1cae87578b1a49e47c281bf7c13/f816d/LayerChatImage_byvyup.png&quot;
        srcset=&quot;/static/e4f6a1cae87578b1a49e47c281bf7c13/8ff5a/LayerChatImage_byvyup.png 240w,
/static/e4f6a1cae87578b1a49e47c281bf7c13/f816d/LayerChatImage_byvyup.png 461w&quot;
        sizes=&quot;(max-width: 461px) 100vw, 461px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;Need help setting this up or just want to chat? Shoot me an email at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to show relative time in Atlas Conversation List Controller (Layer Chat)]]></title><link>https://pulkitgoyal.in/showing-relative-date-in-atlas-conversationlistviewcontroller-with</link><guid isPermaLink="false">https://pulkitgoyal.in/showing-relative-date-in-atlas-conversationlistviewcontroller-with</guid><pubDate>Sat, 25 Apr 2015 06:32:55 GMT</pubDate><content:encoded>&lt;p&gt;Atlas is a fully featured, high performance, 100% customizable UI kit, built by Layer to power communications interfaces in any app. If you want to learn how to integrate chat in your iOS app, take a look at &lt;a href=&quot;https://pulkitgoyal.in/getting-started-with-layer-to-include-chat-in-ios-apps/&quot;&gt;Implementing Chat/Messaging in iOS apps with Layer&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Although, Atlas is highly customizable, there are a few things that it doesn’t have an option to customize. This post explains how you can update the conversation list in Atlas to include relative time for the same day instead of absolute time. Here’s how it looks by default:&lt;/p&gt;
&lt;center&gt;
![](https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,h_465/AtlasConversationListAbsoluteTime_jgn3ft.png)
&lt;/center&gt;
&lt;p&gt;Digging into the code, you will find that the cells in converstaion list are built in &lt;a href=&quot;https://github.com/layerhq/Atlas-iOS/blob/master/Code/Views/ATLConversationTableViewCell.m&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ATLConversationTableViewCell&lt;/code&gt;&lt;/a&gt;. There it defaults to using an absolute time if the date the message was sent on was today. We can create a subclass of the cell and override the date formatting methods to return a relative time instead. Let’s use the &lt;code class=&quot;language-text&quot;&gt;DateTools&lt;/code&gt; library to handle conversion of &lt;code class=&quot;language-text&quot;&gt;NSDate&lt;/code&gt;s to relative time strings. Add this to your &lt;code class=&quot;language-text&quot;&gt;Podfile&lt;/code&gt; and do a &lt;code class=&quot;language-text&quot;&gt;pod install&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;pod &amp;#39;DateTools&amp;#39;, &amp;#39;~&amp;gt; 1.5&amp;#39;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now create a subclass of &lt;code class=&quot;language-text&quot;&gt;ATLConversationTableViewCell&lt;/code&gt; named &lt;code class=&quot;language-text&quot;&gt;PGConversationListTableViewCell&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;//
//  PGConversationListTableViewCell.h
//
#import &amp;quot;ATLConversationTableViewCell.h&amp;quot;
@interface PGConversationListTableViewCell : ATLConversationTableViewCell &amp;lt;ATLConversationPresenting&amp;gt;
@end

//
//  PGConversationListTableViewCell.m
//
#import &amp;quot;PGConversationListTableViewCell.h&amp;quot;
#import &amp;quot;NSDate+DateTools.h&amp;quot;

@interface PGConversationListTableViewCell ()
- (NSString *)dateLabelForLastMessage:(LYRMessage *)lastMessage;
@end

@implementation PGConversationListTableViewCell

- (NSString *)dateLabelForLastMessage:(LYRMessage *)lastMessage {
    if (!lastMessage) return @&amp;quot;&amp;quot;;
    if (!lastMessage.receivedAt) return @&amp;quot;&amp;quot;;
    return lastMessage.receivedAt.timeAgoSinceNow;
}
@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, all we need to do is make Atlas pick up this class instead of the default one when laying out the table view. We can do this when customizing our &lt;code class=&quot;language-text&quot;&gt;ATLConversationListViewController&lt;/code&gt;. If you created a subclass of the conversation list controller, do this somewhere in &lt;code class=&quot;language-text&quot;&gt;viewDidLoad&lt;/code&gt;. Otherwise, set the cell class on the &lt;code class=&quot;language-text&quot;&gt;ATLConversationListViewController&lt;/code&gt; instance when you set up the controller.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;[self setCellClass:[PGConversationListTableViewCell class]];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s how your conversation list should look now. Easy, right?&lt;/p&gt;
&lt;center&gt;
![](https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,h_465/AtlasConversationListRelativeTime_qerwvv.png)
&lt;/center&gt;
&lt;p&gt;Need help setting this up or just want to chat? Shoot me an email at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Implementing Chat/Messaging in iOS apps with Layer]]></title><link>https://pulkitgoyal.in/getting-started-with-layer-to-include-chat-in-ios-apps</link><guid isPermaLink="false">https://pulkitgoyal.in/getting-started-with-layer-to-include-chat-in-ios-apps</guid><pubDate>Thu, 09 Apr 2015 18:49:27 GMT</pubDate><content:encoded>
  &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/a63dccb11f03989d811605ce87d66ce7/7a4b2/Implementing_Chat-Messaging_in_iOS_apps_1_or5whr.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
  
  &lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&amp;apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACRklEQVQoz6VSzU7UUBjtW2hAkZn+9/be23Y6bQeYn5YAJhLYDDoL1JABYtiYaEKCD+ACN6jJRIK6MJq48C0Mr9Xj6WiMC125OLm99557er7vO0bWX4PpurUXCngiQNv3YAc+nCD4Cd9Hy3XQ8lxY/LY8Dy651m9uMEfDbe6Njc3NWkkJFcW4E2g4YYgoThBxH0UR4nwFKsuR5jnyvEBRFEiEQugEcGUIrfjN91JH8zdGVZaINQ91jJbQ8EkQQiCJNDqdBNmgwmq1jlFVoqoq3NveRh7GCC0PouEkCbTWUKEHLR0YvWGJG5aPJV9hOaAYXY339tDpl3CTDF0K7ozHSNIUaRyjQxcrRQ/D0Qg67dB1TkMSifIIlrzaH2DZafrSlKugSJrNZnj3/iM+fPqMx9MjfL++xuXVFS5enmN2foHLV6/x7ctXXLx9g263C1NIGpI0JGEU/SFumu7cXQPJEsZ797E72ceDgyNkw3XscL//6CEmkwmmh1OcvTjDk5MTPD89RZ51YVNw0de4RRjlxmbdorKjYlh06SmJkH1ccnwsmA5kWmBlVKLDh2tZAWX7cBeX4bZsVmZDkWsHYm7GDCMYd7e22ANdZyw15RA8Ti6hy4w96/JssLaKHpH1etjI+yhM3i9Y0G0PAYcRUbBNsdtMyBJhDKuq9jlVSVEh+TfmSzRR+AXBSJjMm0uOYKTCecQiBKzEYvZ8ZlLQhNRqvhrJcFC3KWIrWVsN6S+w/1jtf3BMiplcjcmzp/XO4QF2j6c1gf/FDzgWclldvxcLAAAAAElFTkSuQmCC&amp;apos;); background-size: cover; display: block;&quot;&gt;
      &lt;img class=&quot;gatsby-resp-image-image&quot; style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot; alt=&quot;Implementing Chat Messaging in iOS apps 1 or5whr&quot; title src=&quot;/static/a63dccb11f03989d811605ce87d66ce7/d9199/Implementing_Chat-Messaging_in_iOS_apps_1_or5whr.png&quot; srcset=&quot;/static/a63dccb11f03989d811605ce87d66ce7/8ff5a/Implementing_Chat-Messaging_in_iOS_apps_1_or5whr.png 240w,
/static/a63dccb11f03989d811605ce87d66ce7/e85cb/Implementing_Chat-Messaging_in_iOS_apps_1_or5whr.png 480w,
/static/a63dccb11f03989d811605ce87d66ce7/d9199/Implementing_Chat-Messaging_in_iOS_apps_1_or5whr.png 960w,
/static/a63dccb11f03989d811605ce87d66ce7/7a4b2/Implementing_Chat-Messaging_in_iOS_apps_1_or5whr.png 1240w&quot; sizes=&quot;(max-width: 960px) 100vw, 960px&quot;&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://layer.com/&quot;&gt;Layer&lt;/a&gt; is an open communications layer for the Internet, a platform that enables app creators everywhere to easily add native communications to their products. &lt;/p&gt;
&lt;p&gt;Whether an app is centered around compelling content in sports, entertainment or news — or the focus is finding and buying a concert ticket or a t-shirt, booking a flight or hotel, or hailing a town car or taxi — enabling users to engage with one another in-app and in context is the key to a delightful user experience.&lt;/p&gt;
&lt;p&gt;Layer is one of the easiest ways to integrate chat and messsaging features in your apps. With the recent launch of &lt;a href=&quot;https://atlas.layer.com/&quot;&gt;Atlas&lt;/a&gt;, it is even easier to integrate Layer in your app using its fully featured, high performance, 100% customizable UI kit. &lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;This tutorial explains how to quickly get started with Layer and Atlas to create a simple app to chat between a device and a simulator. &lt;/p&gt;
&lt;h3&gt;Configuration&lt;/h3&gt;
&lt;h4&gt;Set up Layer&lt;/h4&gt;
&lt;p&gt;The first step is to connect the layer client. Add the following to your &lt;code class=&quot;language-text&quot;&gt;AppDelegate.m&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;static NSString *const kLayerAppID = @&amp;quot;LAYER-APP-ID&amp;quot;; // TODO Update layer app id here

// ...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // ...
    
    // Setup Layer
    _layerClient = [LYRClient clientWithAppID:[[NSUUID alloc] initWithUUIDString:kLayerAppID]];
    self.layerClient.autodownloadMIMETypes = [NSSet setWithObjects:ATLMIMETypeImageJPEGPreview, ATLMIMETypeTextPlain, nil];
    [self.layerClient connectWithCompletion:^(BOOL success, NSError *error) {
        if (!success) {
            NSLog(@&amp;quot;Failed to connect to Layer: %@&amp;quot;, error);
        } else {
            // TODO This will usually be in a view controller after the user authenticates
            // For the purposes of this Quick Start project, let&amp;#39;s authenticate as a user named &amp;#39;Device/Simulator&amp;#39;.
    #if TARGET_IPHONE_SIMULATOR
            NSString *userIDString = @&amp;quot;Simulator&amp;quot;;
    #else // TARGET_IPHONE_SIMULATOR
            NSString *userIDString = @&amp;quot;Device&amp;quot;;
    #endif // TARGET_IPHONE_SIMULATOR

            // Once connected, authenticate user.
            // Check Authenticate step for authenticateLayerWithUserID source
            [self authenticateLayerWithUserID:userIDString completion:^(BOOL success, NSError *error) {
                if (!success) {
                    NSLog(@&amp;quot;Failed Authenticating Layer Client with error:%@&amp;quot;, error);
                }
            }];
        }
    }];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Authenticate&lt;/h4&gt;
&lt;p&gt;Once connected, it is time to authenticate the &lt;code class=&quot;language-text&quot;&gt;LYRClient&lt;/code&gt; object. Layer authentication requires that a backend server generate an &lt;code class=&quot;language-text&quot;&gt;Identity Token&lt;/code&gt; on behalf of the client. For testing purposes, Layer provides a sample backend that takes care of this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)authenticateLayerWithUserID:(NSString *)userID completion:(void (^)(BOOL success, NSError * error))completion
{
    // Check to see if the layerClient is already authenticated.
    if (self.layerClient.authenticatedUserID) {
        // If the layerClient is authenticated with the requested userID, complete the authentication process.
        if ([self.layerClient.authenticatedUserID isEqualToString:userID]){
            NSLog(@&amp;quot;Layer Authenticated as User %@&amp;quot;, self.layerClient.authenticatedUserID);
            if (completion) completion(YES, nil);
            return;
        } else {
            //If the authenticated userID is different, then deauthenticate the current client and re-authenticate with the new userID.
            [self.layerClient deauthenticateWithCompletion:^(BOOL success, NSError *error) {
                if (!error){
                    [self authenticationTokenWithUserId:userID completion:^(BOOL success, NSError *error) {
                        if (completion){
                            completion(success, error);
                        }
                    }];
                } else {
                    if (completion){
                        completion(NO, error);
                    }
                }
            }];
        }
    } else {
        // If the layerClient isn&amp;#39;t already authenticated, then authenticate.
        [self authenticationTokenWithUserId:userID completion:^(BOOL success, NSError *error) {
            if (completion){
                completion(success, error);
            }
        }];
    }
}

- (void)authenticationTokenWithUserId:(NSString *)userID completion:(void (^)(BOOL success, NSError* error))completion{

    /*
     * 1. Request an authentication Nonce from Layer
     */
    [self.layerClient requestAuthenticationNonceWithCompletion:^(NSString *nonce, NSError *error) {
        if (!nonce) {
            if (completion) {
                completion(NO, error);
            }
            return;
        }

        /*
         * 2. Acquire identity Token from Layer Identity Service
         */
        [self requestIdentityTokenForUserID:userID appID:[self.layerClient.appID UUIDString] nonce:nonce completion:^(NSString *identityToken, NSError *error) {
            if (!identityToken) {
                if (completion) {
                    completion(NO, error);
                }
                return;
            }

            /*
             * 3. Submit identity token to Layer for validation
             */
            [self.layerClient authenticateWithIdentityToken:identityToken completion:^(NSString *authenticatedUserID, NSError *error) {
                if (authenticatedUserID) {
                    if (completion) {
                        completion(YES, nil);
                    }
                    NSLog(@&amp;quot;Layer Authenticated as User: %@&amp;quot;, authenticatedUserID);
                } else {
                    completion(NO, error);
                }
            }];
        }];
    }];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The following code snippet connects to the sample &lt;code class=&quot;language-text&quot;&gt;Layer Identity Service&lt;/code&gt;, generates an Identity Token on behalf your application, and authenticates the &lt;code class=&quot;language-text&quot;&gt;LYRClient&lt;/code&gt;. Note that in production apps, you would need to update it to communicate with your backend and generate a token for Layer. Please check out the &lt;a href=&quot;https://developer.layer.com/docs/guides/ios#authentication&quot;&gt;Layer Authentication Guide&lt;/a&gt; for setting up your backend for this.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)requestIdentityTokenForUserID:(NSString *)userID appID:(NSString *)appID nonce:(NSString *)nonce completion:(void(^)(NSString *identityToken, NSError *error))completion
{
    NSParameterAssert(userID);
    NSParameterAssert(appID);
    NSParameterAssert(nonce);
    NSParameterAssert(completion);

    NSURL *identityTokenURL = [NSURL URLWithString:@&amp;quot;https://layer-identity-provider.herokuapp.com/identity_tokens&amp;quot;];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:identityTokenURL];
    request.HTTPMethod = @&amp;quot;POST&amp;quot;;
    [request setValue:@&amp;quot;application/json&amp;quot; forHTTPHeaderField:@&amp;quot;Content-Type&amp;quot;];
    [request setValue:@&amp;quot;application/json&amp;quot; forHTTPHeaderField:@&amp;quot;Accept&amp;quot;];

    NSDictionary *parameters = @{ @&amp;quot;app_id&amp;quot;: appID, @&amp;quot;user_id&amp;quot;: userID, @&amp;quot;nonce&amp;quot;: nonce };
    NSData *requestBody = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
    request.HTTPBody = requestBody;

    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            completion(nil, error);
            return;
        }

        // Deserialize the response
        NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        if(![responseObject valueForKey:@&amp;quot;error&amp;quot;])
        {
            NSString *identityToken = responseObject[@&amp;quot;identity_token&amp;quot;];
            completion(identityToken, nil);
        }
        else
        {
            NSString *domain = @&amp;quot;layer-identity-provider.herokuapp.com&amp;quot;;
            NSInteger code = [responseObject[@&amp;quot;status&amp;quot;] integerValue];
            NSDictionary *userInfo =
            @{
               NSLocalizedDescriptionKey: @&amp;quot;Layer Identity Provider Returned an Error.&amp;quot;,
               NSLocalizedRecoverySuggestionErrorKey: @&amp;quot;There may be a problem with your APPID.&amp;quot;
            };

            NSError *error = [[NSError alloc] initWithDomain:domain code:code userInfo:userInfo];
            completion(nil, error);
        }

    }] resume];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;Building the UI&lt;/h3&gt;
&lt;h4&gt;Participant&lt;/h4&gt;
&lt;p&gt;A participant is a user that participates in a conversation. It contains information for Atlas to render the details about the user when displaying conversations. Create a class &lt;code class=&quot;language-text&quot;&gt;PGUser&lt;/code&gt; that implements the &lt;code class=&quot;language-text&quot;&gt;ATLParticipant&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;ATLAvatarItem&lt;/code&gt; protocols. For the simple example, it uses the participant identifier as all properties of the users, but you will need to modify it to fetch these properties from your API based on the participant identifier. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;// PGUser.h
@interface PGUser : NSObject &amp;lt;ATLParticipant, ATLAvatarItem&amp;gt;

@property(nonatomic, readonly) NSString *firstName;
@property(nonatomic, readonly) NSString *lastName;
@property(nonatomic, readonly) NSString *fullName;
@property(nonatomic, readonly) NSString *participantIdentifier;
@property(nonatomic, readonly) UIImage *avatarImage;
@property(nonatomic, readonly) NSString *avatarInitials;

- (instancetype)initWithParticipantIdentifier:(NSString *)participantIdentifier;

+ (instancetype)userWithParticipantIdentifier:(NSString *)participantIdentifier;


@end

// PGUser.m
@implementation PGUser

- (instancetype)initWithParticipantIdentifier:(NSString *)participantIdentifier {
    self = [super init];
    if (self) {
        _participantIdentifier = participantIdentifier;
        _firstName = participantIdentifier;
        _lastName = participantIdentifier;
        _fullName = participantIdentifier;
        _avatarInitials = [participantIdentifier substringToIndex:1];
    }

    return self;
}

+ (instancetype)userWithParticipantIdentifier:(NSString *)participantIdentifier {
    return [[self alloc] initWithParticipantIdentifier:participantIdentifier];
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Show all user conversations&lt;/h4&gt;
&lt;p&gt;The user is now authenticated to Layer. Let’s grab and show all conversations the user is currently involved in. Create a subclass &lt;code class=&quot;language-text&quot;&gt;PGConversationListViewController&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;ATLConversationListViewController&lt;/code&gt;. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;// PGConversationListViewController.h
@interface PGConversationListViewController : ATLConversationListViewController &amp;lt;ATLParticipantTableViewControllerDelegate&amp;gt;
- (void)selectConversation:(LYRConversation *)conversation;
+ (NSSet *)participants;
@end


// PGConversationListViewController.m
@implementation PGConversationListViewController
- (void)viewDidLoad {
    [super viewDidLoad];
	
    // Set data source and delegate
    self.dataSource = self;
    self.delegate = self;

	// Add a create chat button
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(createNewChat:)];
}

#pragma mark - Conversation List Data Source

- (NSString *)conversationListViewController:(ATLConversationListViewController *)conversationListViewController titleForConversation:(LYRConversation *)conversation {
    NSMutableSet *participantIdentifiers = [conversation.participants mutableCopy];
    [participantIdentifiers minusSet:[NSSet setWithObject:self.layerClient.authenticatedUserID]];

    if (participantIdentifiers.count == 0) return @&amp;quot;Personal Conversation&amp;quot;;
    NSMutableSet *participants = [[self participantsForIdentifiers:participantIdentifiers] mutableCopy];
    if (participants.count == 0) return @&amp;quot;No Matching Participants&amp;quot;;
    if (participants.count == 1) return [[participants allObjects][0] fullName];

    NSMutableArray *firstNames = [NSMutableArray new];
    [participants enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {
        id &amp;lt;ATLParticipant&amp;gt; participant = obj;
        if (participant.firstName) {
            // Put the last message sender&amp;#39;s name first
            if ([conversation.lastMessage.sentByUserID isEqualToString:participant.participantIdentifier]) {
                [firstNames insertObject:participant.firstName atIndex:0];
            } else {
                [firstNames addObject:participant.firstName];
            }
        }
    }];
    NSString *firstNamesString = [firstNames componentsJoinedByString:@&amp;quot;, &amp;quot;];
    return firstNamesString;
}

#pragma mark - Conversation List Delegate

- (void)conversationListViewController:(ATLConversationListViewController *)conversationListViewController didSelectConversation:(LYRConversation *)conversation {
    [self presentConversationControllerForConversation:conversation];
}

#pragma mark - Participant Delegate

- (void)participantTableViewController:(ATLParticipantTableViewController *)participantTableViewController didSelectParticipant:(id &amp;lt;ATLParticipant&amp;gt;)participant {
    [self.navigationController popViewControllerAnimated:NO];

    // Create a new conversation
    NSError *error = nil;
    LYRConversation *conversation = [self.layerClient newConversationWithParticipants:[NSSet setWithArray:@[self.layerClient.authenticatedUserID, participant.participantIdentifier]] options:nil error:&amp;amp;error];
    if (!conversation) {
        NSLog(@&amp;quot;New Conversation creation failed: %@&amp;quot;, error);
    } else {
        [self presentConversationControllerForConversation:conversation];
    }
}

- (void)participantTableViewController:(ATLParticipantTableViewController *)participantTableViewController didSearchWithString:(NSString *)searchText completion:(void (^)(NSSet *filteredParticipants))completion {
}

#pragma mark - Helpers

- (void)presentConversationControllerForConversation:(LYRConversation *)conversation {
    ATLConversationViewController *conversationViewController = [PGConversationViewController conversationViewControllerWithLayerClient:self.layerClient];
    conversationViewController.conversation = conversation;
    [self.navigationController pushViewController:conversationViewController animated:YES];
}

- (NSSet *)participantsForIdentifiers:(NSSet *)identifiers {
    NSMutableSet *participants = [[NSMutableSet alloc] initWithCapacity:identifiers.count];
    for (NSString *identifier in identifiers) {
        [participants addObject:[PGUser userWithParticipantIdentifier:identifier]];
    }
    return participants;
}

#pragma mark - User Interaction

- (void)createNewChat:(id)sender {
    ATLParticipantTableViewController *participantTableViewController = [ATLParticipantTableViewController participantTableViewControllerWithParticipants:[PGConversationListViewController participants] sortType:ATLParticipantPickerSortTypeFirstName];
    participantTableViewController.delegate = self;
    [self.navigationController pushViewController:participantTableViewController animated:YES];
}

#pragma mark - Static

+ (NSSet *)participants {

    __block NSSet *participants;
    static dispatch_once_t onceToken;
    dispatch_once(&amp;amp;onceToken, ^{
        participants = [NSSet setWithArray:@[[PGUser userWithParticipantIdentifier:@&amp;quot;Device&amp;quot;], [PGUser userWithParticipantIdentifier:@&amp;quot;Simulator&amp;quot;]]];
    });
    return participants;
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just present this controller to open all chats the user is currently involved in. Let’s present this from our &lt;code class=&quot;language-text&quot;&gt;AppDelegate&lt;/code&gt; for now. Add this to the end of &lt;code class=&quot;language-text&quot;&gt;application:didFinishLaunchingWithOptions:&lt;/code&gt; (Note: It assumes that the initial view controller in the storyboard is a &lt;code class=&quot;language-text&quot;&gt;UINavigationController&lt;/code&gt;)&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;UINavigationController *navigationController = (UINavigationController *) self.window.rootViewController; 
self.conversationListViewController = [LCConversationListViewController conversationListViewControllerWithLayerClient:self.layerClient];
[navigationController pushViewController:self.conversationListViewController animated:NO];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h4&gt;Show all messages in a conversation&lt;/h4&gt;
&lt;p&gt;Now that we have all the conversations the user is involved in, let’s see how we can show all messages inside a single conversation. Create a subclass &lt;code class=&quot;language-text&quot;&gt;PGConversationViewController&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;ATLConversationViewController&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;// PGConversationViewController.h
@interface PGConversationViewController : ATLConversationViewController &amp;lt;ATLConversationViewControllerDataSource, ATLConversationViewControllerDelegate&amp;gt;

@end

// PGConversationViewController.m
@implementation PGConversationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.delegate = self;
    self.dataSource = self;
}

#pragma mark - Conversation Data Source

- (id &amp;lt;ATLParticipant&amp;gt;)conversationViewController:(ATLConversationViewController *)conversationViewController participantForIdentifier:(NSString *)participantIdentifier {
    // TODO Return the user corresponding to this participant identifier
    return [PGUser userWithParticipantIdentifier:participantIdentifier];
}

- (NSAttributedString *)conversationViewController:(ATLConversationViewController *)conversationViewController attributedStringForDisplayOfDate:(NSDate *)date {
    return [[NSAttributedString alloc] initWithString:[NSDateFormatter localizedStringFromDate:date dateStyle:NSDateFormatterShortStyle timeStyle:NSDateFormatterShortStyle]];
}

- (NSAttributedString *)conversationViewController:(ATLConversationViewController *)conversationViewController attributedStringForDisplayOfRecipientStatus:(NSDictionary *)recipientStatus {
    NSMutableDictionary *mutableRecipientStatus = [recipientStatus mutableCopy];
    if ([mutableRecipientStatus valueForKey:self.layerClient.authenticatedUserID]) {
        [mutableRecipientStatus removeObjectForKey:self.layerClient.authenticatedUserID];
    }

    NSString *statusString = [NSString new];
    if (mutableRecipientStatus.count &amp;gt; 1) {
        __block NSUInteger readCount = 0;
        __block BOOL delivered;
        __block BOOL sent;
        [mutableRecipientStatus enumerateKeysAndObjectsUsingBlock:^(NSString *userID, NSNumber *statusNumber, BOOL *stop) {
            LYRRecipientStatus status = (LYRRecipientStatus) statusNumber.integerValue;
            switch (status) {
                case LYRRecipientStatusInvalid:
                    break;
                case LYRRecipientStatusSent:
                    sent = YES;
                    break;
                case LYRRecipientStatusDelivered:
                    delivered = YES;
                    break;
                case LYRRecipientStatusRead:
                    NSLog(@&amp;quot;Read&amp;quot;);
                    readCount += 1;
                    break;
            }
        }];
        if (readCount) {
            NSString *participantString = readCount &amp;gt; 1 ? @&amp;quot;Participants&amp;quot; : @&amp;quot;Participant&amp;quot;;
            statusString = [NSString stringWithFormat:@&amp;quot;Read by %lu %@&amp;quot;, (unsigned long) readCount, participantString];
        } else if (delivered) {
            statusString = @&amp;quot;Delivered&amp;quot;;
        } else if (sent) {
            statusString = @&amp;quot;Sent&amp;quot;;
        }
    } else {
        __block NSString *blockStatusString = [NSString new];
        [mutableRecipientStatus enumerateKeysAndObjectsUsingBlock:^(NSString *userID, NSNumber *statusNumber, BOOL *stop) {
            if ([userID isEqualToString:self.layerClient.authenticatedUserID]) return;
            LYRRecipientStatus status = (LYRRecipientStatus) statusNumber.integerValue;
            switch (status) {
                case LYRRecipientStatusInvalid:
                    blockStatusString = @&amp;quot;Not Sent&amp;quot;;
                case LYRRecipientStatusSent:
                    blockStatusString = @&amp;quot;Sent&amp;quot;;
                case LYRRecipientStatusDelivered:
                    blockStatusString = @&amp;quot;Delivered&amp;quot;;
                    break;
                case LYRRecipientStatusRead:
                    blockStatusString = @&amp;quot;Read&amp;quot;;
                    break;
            }
        }];
        statusString = blockStatusString;
    }
    return [[NSAttributedString alloc] initWithString:statusString attributes:@{NSFontAttributeName : [UIFont boldSystemFontOfSize:11]}];

}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;That’s all you need to integrate a chat in your application. Need help setting this up or just want to chat? Shoot me an email at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Organizing ChromeApp Development with Grunt]]></title><link>https://pulkitgoyal.in/organizing-chromeapp-development-with-grunt</link><guid isPermaLink="false">https://pulkitgoyal.in/organizing-chromeapp-development-with-grunt</guid><pubDate>Sun, 22 Mar 2015 14:45:59 GMT</pubDate><content:encoded>
  &lt;a class=&quot;gatsby-resp-image-link&quot; href=&quot;/static/89b1fe90649bda2370239c7e46991c0a/dd45a/logo_xaxc06.png&quot; style=&quot;display: block&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;
  
  &lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position: relative; display: block;  max-width: 550px; margin-left: auto; margin-right: auto;&quot;&gt;
    &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom: 36.25%; position: relative; bottom: 0; left: 0; background-image: url(&amp;apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAHCAIAAACHqfpvAAAACXBIWXMAAAsSAAALEgHS3X78AAABUElEQVQY02O4een40R3L1i2duXvjkiPbFn3+9OH///9///79B0T/gAQQ/PmPAzCc2jZzThzLmQ6R7WW8c3OUP71/DRT98/s3UCdEBdCAnz++A0VAbJggVPOJFWX7G2TeLVS4N0N1Z4Pq/Wunjx3cuXbx9CWzeo7s27pkVi+QvXbJjA/v3kA0wwFI87n17YdaDe5Nk73Yp3Gg0/7pnUu7t6xZOX/Szo3Ld21asW3t4j1bVl86c+zH9+8gX/z5AyQQNt+8duVSt8rf1ZLf5gscnp328dvfW1fPXr1w6u7Nq1fOn7x45tj1S2fPnzx86ezx08f2nT91GEhePncCyPj44R3D4X07phQ5nGzl31wpObM158XzZ0Ajv3z6CEKfP336+P7zxw9AEuhtYFh+//4VKAhCXz79+fOH4duPn2umVx5vlN5cZ3jyyG6wx/7+Jw4AANRXXJ+wcPeLAAAAAElFTkSuQmCC&amp;apos;); background-size: cover; display: block;&quot;&gt;
      &lt;img class=&quot;gatsby-resp-image-image&quot; style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot; alt=&quot;logo xaxc06&quot; title src=&quot;/static/89b1fe90649bda2370239c7e46991c0a/dd45a/logo_xaxc06.png&quot; srcset=&quot;/static/89b1fe90649bda2370239c7e46991c0a/8ff5a/logo_xaxc06.png 240w,
/static/89b1fe90649bda2370239c7e46991c0a/e85cb/logo_xaxc06.png 480w,
/static/89b1fe90649bda2370239c7e46991c0a/dd45a/logo_xaxc06.png 550w&quot; sizes=&quot;(max-width: 550px) 100vw, 550px&quot;&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    
&lt;p&gt;Chrome Apps deliver an experience as capable as a native app, but as safe as a web page. Just like web apps, Chrome Apps are written in HTML5, JavaScript, and CSS. But Chrome Apps look and behave like native apps, and they have native-like capabilities that are much more powerful than those available to web apps.&lt;/p&gt;
&lt;p&gt;The Grunt ecosystem is huge and it’s growing every day. With literally hundreds of plugins to choose from, you can use Grunt to automate just about anything with a minimum of effort. Here is what we used to automate our tasks for developing, building and publishing the chrome app all with grunt.&lt;/p&gt;
&lt;h4&gt;Develop&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/stephenplusplus/grunt-wiredep&quot;&gt;grunt-wiredep&lt;/a&gt;: Inject Bower packages into your source code with Grunt. Just run this task after you install a new dependency with bower and it will insert it in areas marked inside your html file.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- bower:js --&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- endbower --&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s what our configuration for the task looks like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;wiredep&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    app&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        src&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/index.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        ignorePath&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/yeoman/grunt-usemin&quot;&gt;grunt-usemin&lt;/a&gt;: Replaces references from non-optimized scripts, stylesheets and other assets to their optimized version within a set of HTML files (or any templates/views). Just add all your scripts in html inside a &lt;code class=&quot;language-text&quot;&gt;build&lt;/code&gt; block and get another file with generated scripts/html optimized for deployment.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- build:js js/app.js --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;js/app.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;js/controllers/thing-controller.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;js/models/thing-model.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;js/views/thing-view.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- endbuild --&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s how our &lt;code class=&quot;language-text&quot;&gt;usemin&lt;/code&gt; configuration looks like:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;usemin&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        assetsDirs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.dist %&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.dist %&gt;/images&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    html&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.dist %&gt;/{,*/}*.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    css&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.dist %&gt;/styles/{,*/}*.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
useminPrepare&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        dest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.dist %&gt;&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    html&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;/index.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;/player.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/jsoverson/grunt-env&quot;&gt;grunt-env&lt;/a&gt;, &lt;a href=&quot;https://github.com/jsoverson/grunt-preprocess&quot;&gt;grunt-preprocess&lt;/a&gt; and &lt;a href=&quot;https://github.com/gruntjs/grunt-contrib-copy&quot;&gt;grunt-contrib-copy&lt;/a&gt;: Use grunt-env to specify different environment variables for different targets. It works great when coupled with grunt-preprocess which can trim out the code based on the environment. For example, to have different app names for staging and production, you could do the following in `manifest.json:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;!-- @echo APP_NAME --&gt;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
...
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s the configuration:&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Apply environment variables&lt;/span&gt;
env&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    staging&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;APP_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;App Dev&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    prod&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token constant&quot;&gt;APP_NAME&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;App&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Copy files from `app` directory to `processed` directory&lt;/span&gt;
copy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    preprocess&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        expand&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        cwd&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        dest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        src&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;**&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Preprocess all js, html and json files inside the `processed` directory&lt;/span&gt;
preprocess&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    inline&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        src&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;/js/{,*/}*.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;/*.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;/*.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            inline&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gruntjs/grunt-contrib-jshint&quot;&gt;grunt-contrib-jshint&lt;/a&gt;: Make sure code styles are up to par and there are no obvious mistakes.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Make sure code styles are up to par and there are no obvious mistakes&lt;/span&gt;
jshint&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        jshintrc&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.jshintrc&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        reporter&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;jshint-stylish&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    all&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;Gruntfile.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;/js/{,*/}*.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;!&amp;lt;%= config.processed %&gt;/js/vendor/*&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;test/spec/{,*/}*.js&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/gruntjs/grunt-contrib-watch&quot;&gt;grunt-contrib-watch&lt;/a&gt;: Run predefined tasks whenever watched file patterns are added, changed or deleted.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;watch&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Run the wiredep task whenever bower.json changes&lt;/span&gt;
bower&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    files&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;bower.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    tasks&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;wiredep&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;copy:preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Run preprocess and jshint whenever any js file changes&lt;/span&gt;
js&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    files&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/js/**/*.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    tasks&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;copy:preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;jshint&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        livereload&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;45729&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Run preprocess whenever any css file changes&lt;/span&gt;
styles&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    files&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/styles/{,*/}*.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    tasks&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;copy:preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        livereload&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;45729&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Reload the app on any significant changes&lt;/span&gt;
livereload&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    tasks&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;copy:preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        livereload&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;45729&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    files&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;.tmp/styles/{,*/}*.css&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/*.html&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/manifest.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/_locales/{,*/}*.json&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Build and Deploy&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ragingwind/grunt-chrome-manifest&quot;&gt;grunt-chrome-manifest&lt;/a&gt;: Grunt task for Chrome manifest.json&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Merge event page, update build number, exclude the debug script&lt;/span&gt;
chromeManifest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    dist&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        	&lt;span class=&quot;token comment&quot;&gt;// Don&apos;t increase the build number automatically&lt;/span&gt;
            buildnumber&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            background&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                target&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;js/background.js&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;token comment&quot;&gt;// Exclude files used for development&lt;/span&gt;
                exclude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                    &lt;span class=&quot;token string&quot;&gt;&apos;js/chromereload.js&apos;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        src&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        dest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.dist %&gt;&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vojtajina/grunt-bump&quot;&gt;grunt-bump&lt;/a&gt;: Automatically bump version numbers, create tags, commit releases etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Increments the version&lt;/span&gt;
bump&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	    &lt;span class=&quot;token comment&quot;&gt;// Update the version in package.json, manifest.json and commit the changes&lt;/span&gt;
        files&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;package.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/manifest.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        updateConfigs&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        commit&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        commitMessage&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Release v%VERSION%&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        commitFiles&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;package.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.app %&gt;/manifest.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        createTag&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        push&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        pushTo&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;upstream&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        gitDescribeOptions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;--tags --always --abbrev=1 --dirty=-d&apos;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gruntjs/grunt-contrib-compress&quot;&gt;grunt-contrib-compress&lt;/a&gt; and &lt;a href=&quot;https://github.com/c301/grunt-webstore-upload&quot;&gt;grunt-webstore-upload&lt;/a&gt;: Compress the packaged app and automate uploading process of the new versions of Chrome Extension or App to Chrome Webstore.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Copmress files inside processed directory and create a new package ready for upload&lt;/span&gt;
&lt;span class=&quot;token function-variable function&quot;&gt;compress&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;grunt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        dist&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token function-variable function&quot;&gt;archive&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; manifest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readJSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;template&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.processed %&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/manifest.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;template&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;%= config.package %&gt;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/App-&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; manifest&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;version &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.zip&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            files&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    expand&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    cwd&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dist/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    src&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;**&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                    dest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Uploads latest build from package to production/staging&lt;/span&gt;
webstore&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        publish&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        client_id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;XXXX&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        client_secret&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;XXXX&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&quot;staging&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        options&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            appID&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;XXXX&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
            zip&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;%= config.package %&gt;&quot;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Uploads the most recent zip file from this directory&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Putting everything together: Lets put all the tasks together into more manageable defaults for our development and deployment.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Configurable paths&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    app&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;app&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    dist&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dist&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    processed&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;processed&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;package&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    tasks&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cli&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tasks
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Loads task options from `tasks/options/` and loads tasks defined in `package.json`&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Read more here: https://www.thomasboyt.com/2013/09/01/maintainable-grunt.html&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;load-grunt-config&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;grunt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    configPath&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;process&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cwd&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;tasks/options&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    init&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        pkg&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;readJSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;package.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        manifest&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;manifest&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; config
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; target &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;target&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;dev&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// `grunt debug [--target=dev|test|staging|prod]` - Default, run Chrome App on Chrome app container&lt;/span&gt;
grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;debug&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Task for development of the app. Enables live reload&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;clean&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;env:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;copy:preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;watch&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Creates a production/staging build and archives to zip file&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// grunt build [--target=dev|test|staging|prod]&lt;/span&gt;
grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;build&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Creates a production/staging build and archives to zip file&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;env:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;clean:dist&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;copy:preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;preprocess&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;chromeManifest:dist&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;useminPrepare&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;concat&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;cssmin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;uglify&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;copy:dist&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;copy:styles&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;usemin&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;compress&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Publish the application on the web store. Automatically increases the build version, uploads the build and commits the updated files.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// grunt publish [--release=major|minor|patch] [--target=staging|prod] [--setversion=x.x.x]&lt;/span&gt;
grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerTask&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;publish&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;Publish the application on the web store&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;bump-only:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; release&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;build&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;webstore_upload:&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; target&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&apos;bump-commit&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;By the way, if you enjoy movies and tv shows, check out our &lt;a href=&quot;https://chrome.google.com/webstore/detail/movietabs/ofaifffanpfcpkpalipnjjehhldopcnm&quot;&gt;MovieTabs extension&lt;/a&gt; for Chrome to discover new movies and tv shows with every tab.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Things you should know about Auto Layout on iOS]]></title><link>https://pulkitgoyal.in/things-you-should-know-about-auto-layout-on-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/things-you-should-know-about-auto-layout-on-ios</guid><pubDate>Thu, 11 Dec 2014 11:02:17 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/4f4066899742e455d7b2bbd37c78d599/7a4b2/Auto_Layout_utismv.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 56.25%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAALCAYAAAB/Ca1DAAAACXBIWXMAAA7EAAAOxAGVKw4bAAABlElEQVQoz5WSO6/aQBCF/f8lOgoqGgqUggKUmjJprpQoCjKx74WLMQbb62fwM8CX3U2MnEQRyUijnZ1dnZlzZoyyamiu0Fyglq7i6hsUMn+5yEDa9Xrldrv9cfa9yxkiKXBEixuW2G7GIfyKKyqitKCuK278nxm2E/P2nYf57BGJEGvr4kc5ddPSti3n8xnTNPE8T59CCFarFUEQaI/jWL/Ztk0URRjmNuLN0uHLq6BtGpKs5BSmFEVJVZaU0ufzOcPhkMlkwnQ6ZblcMpvNGI/HLBYLBoMBo9GIzWaD4QU5H6wY9xiTZTnewcM/nnRl1Z0C7HQsioI8z6mqSnfqOI7O9XU2lE7KAhHz9HmjaadZhuu6hGF4B1SmCux2O03xdDqx3+917hcN67pBQuP5gvcfX3Bet7LTjCRJpCbxHVBV/5v1p200UjeZ4nD0efpk8fJsy8o/uvN9/07p9/Xox/2CPwHRFC3LZr1e64mpu/KOUgfycG06QCW00kZppMRWE1MapWkqF/zykPYd8NGnfmf/AvgdmIdIE5vmpzUAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Auto Layout utismv&quot;
        title=&quot;&quot;
        src=&quot;/static/4f4066899742e455d7b2bbd37c78d599/d9199/Auto_Layout_utismv.png&quot;
        srcset=&quot;/static/4f4066899742e455d7b2bbd37c78d599/8ff5a/Auto_Layout_utismv.png 240w,
/static/4f4066899742e455d7b2bbd37c78d599/e85cb/Auto_Layout_utismv.png 480w,
/static/4f4066899742e455d7b2bbd37c78d599/d9199/Auto_Layout_utismv.png 960w,
/static/4f4066899742e455d7b2bbd37c78d599/7a4b2/Auto_Layout_utismv.png 1240w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;After spending some time with developers working with iOS, I have noticed that a lot of developers out there struggle with &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/Introduction/Introduction.html&quot;&gt;Auto Layout&lt;/a&gt;. I have found that there are a few simple rules that you need to understand to make working with auto layout a delight. Most of the following will depend on how your views are layed out, but this is usually what I do when laying out views in the storyboard.&lt;/p&gt;
&lt;h2&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Auto Layout is a system that lets you lay out your app’s user interface by creating a mathematical description of the relationships between the elements. You define these relationships in terms of constraints either on individual elements, or between sets of elements. Using Auto Layout, you can create a dynamic and versatile interface that responds appropriately to changes in screen size, device orientation, and localization.&lt;/p&gt;
&lt;p&gt;Auto Layout is on by default for new projects that you create in XCode. The typical workflow for designing with Auto Layout is to create, reposition, resize and customize your views and then set up the constraints for the views so that they maintain their position on all devices. With the introduction of&lt;/p&gt;
&lt;p&gt;Until now, if your designs were reasonably complex, you had to write a lot of code to support such adaptive layouts. Not only does Auto Layout makes it easy to support different screen sizes in your apps, as a bonus it also makes internationalization almost trivial.&lt;/p&gt;
&lt;h2&gt;The basics&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You can specify constraints to pin the spacing between views, to pin the dimension of the views or to define the alignment of the views.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a666992fbd6cd98bd970c8c7c50d1dc1/5a46d/Pin_hlrlcx.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 300px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 125.83333333333333%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAZCAIAAAC+dZmEAAAACXBIWXMAAAsSAAALEgHS3X78AAADE0lEQVQ4y4VU2W6bQBTt/z/0Y/pSqalUVVW8m82A2XdmgIEBEsd2rNTuYbGVVEl7HtBouOeu586ny+XyuwcO5/P5djifLy8vL8fj6fn5+XQ6tW1bliXvUdf1Q49PMH18fNxut4IgKIqCQ/fVNXWjhGHYNDWvSl5VYFZXZFkGPlgdGV43ijKfz2ezqapqi/n852T59cd0Y/oZ3yVFU/G6qUc0TUMpha+RjEyQw36/f3p6wtXpdJwZ+ZdFxA+XrHlWfJ7kvEUKr8iIP5JxNWSFQwVPVZUW3Kc1IQUpalK2CIzbodp3yAMz8IP94YD27B5bnmecFQ9VmQQ+IQTNOxwOMPuQnOc56kcJvC+yIJTlBdrDGIMpfv2L3IzojPwg2O92mBO8gYbb+qOaBzKQUZpnNInjra4XBcM9TJMkRea3AB9ErmtV364lFdMOgkDXNMzctm18NU3Li2JI7J1u43vYNUF5/KY/xIFrWpbn+XEc+75nGCayGEQGszfkfgaV6+Sq4kmS5AdRcx3eFaVlmWjn8XgEeShhJFcVb9taVehsaiyXM8d2kNsw1bFJdb3ZbHAD5YPzTmTLzDQ1XK0WhmF0UusGNgKjQgswZ6iw5vxN5N4AZCJLjm1btuPIsmxZNmLe+DcV4vx35KblGzm9/6VNpveSKGFFVmvhNr/By/tzxo+25aqSzia6LAmYEzZMFEVke9NG/Xar3kZuuKami7k5mdzLcreecAGdDoP9Dxmb5Ll0qweOYxPIKSVRFKUpgbayPK9eD60s0TB8x5cEXYDsHZutl6Yorgmhrus6juN5nq7rkApM2RV5DwRH84eXpIESp9OJqiqqqq7WqyiORUE0TRM5gVmMgECzJIlxQlgsaUdGGXEU2bYT9vB9PwojMD3XTXsgFGMFYyljPmOh62xNwwzDYEi7grMhyDBMuEiThBICbSB5SjPEzKhG02VZaNpmeXf3XRDWHRl6Qg3kFRANK4FDAheURlEYhEkaCKnyOYtWkKAsS6ZhdOTX6N7ry6VL3vMsy0LP4WJwhL5WJesXoR2ehz8DXlWOPsNyCAAAAABJRU5ErkJggg==&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Pin&quot;
        title=&quot;&quot;
        src=&quot;/static/a666992fbd6cd98bd970c8c7c50d1dc1/5a46d/Pin_hlrlcx.png&quot;
        srcset=&quot;/static/a666992fbd6cd98bd970c8c7c50d1dc1/8ff5a/Pin_hlrlcx.png 240w,
/static/a666992fbd6cd98bd970c8c7c50d1dc1/5a46d/Pin_hlrlcx.png 300w&quot;
        sizes=&quot;(max-width: 300px) 100vw, 300px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    

  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/79d376bf171b9bb4f1b111ab83964447/5a46d/Align_ziggks.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 300px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 99.16666666666667%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAAsSAAALEgHS3X78AAACxklEQVQ4y2VUiXKiQBT0//9h/2VNJILctyIsIPd9Ka5ntoGYmE0XNTVMTb/uN+/NzG632/1+f/+G+/MK5qfT6XK5HA6HoiiqEU3TtG07w0zXNEmW1pu1pqmKohiGgRVA13VFUS3LKssStPyBdETXdbMiLwSee5kvCYJkWfZlPicWC47jeF5YDiARrh7RjgAHemEYDspZlh+Pe44JWMbgOFqWFZblSJLE7r7vYRW7obzf76/XK8yfz+c8y6MoGsiY1XXJ0i69UlmWgSBFrVY0XTxQjgB5YiJ/OP8gQ7lpKppyV6QmijxBvIEfJ0n1hGcygIhfttt2IBMLkeMYyDIM63nepPlM/rSdZdnDdp5XVaHIviCsdV1zbFuSZUEQuq5F2lMIjNh6fOBLGWTkrMq+JBqapkiSrKoo0hrH5vs+6jnljK39CBzhl/Jkm3yzKVIVJV4UJYEXGIYxttvR1P+2Abj5ljPIry88TZM0TaMx4NwPBtlP2yDfrhd818u5yL/lXOoq6gzPoiIrcIt6YPfUGKhz2zZ109X7v2V3LLpjlBZR9FDGuYj8Tha3lmkMvYlz07X1eu06DppU1TRza7zp8TZssuaYVL3mFn4QIubD9tImXoUlSaAfkTBFUjzPK7JMURS6zTJNbhvbyb7sb0lzUu00QM5NM5C7rrHMTNf+bLeGaZobw9hsNp7nK6qC5PFTN02axHVV9Yf+sD/gilRjC+Bi5LIkUdRSVRVRElVFdWwHso7jTnUG4jjGNUoSfEkcB57nImEc+3Bgu93OtCx0leM6rusGQYC0bdv2PR+Lvh9kH0izLEwzNy9cUWRlWZ4Na2mK8BgxRyzo7Hbg+IjiOEM4rCQj4mgTeossGYo6/z2foWPiH0CgiYkxGoFYiBgFVqD+yrxlGMXGRp+9/8D0BqFDCIIAH0lBHJXDk9K0XV131ce70P4DZMU0tP5X6IsAAAAASUVORK5CYII=&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;Align&quot;
        title=&quot;&quot;
        src=&quot;/static/79d376bf171b9bb4f1b111ab83964447/5a46d/Align_ziggks.png&quot;
        srcset=&quot;/static/79d376bf171b9bb4f1b111ab83964447/8ff5a/Align_ziggks.png 240w,
/static/79d376bf171b9bb4f1b111ab83964447/5a46d/Align_ziggks.png 300w&quot;
        sizes=&quot;(max-width: 300px) 100vw, 300px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Try to keep &lt;code class=&quot;language-text&quot;&gt;Update Frames&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;None&lt;/code&gt; unless you are sure that your auto layout constraints are complete for the view you are positioning. When you update frames, XCode tries to position the views by satisfying the constraints and if the constraints are not complete, most of the times, it will end up resizing your view to &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; width/height. If you do leave &lt;code class=&quot;language-text&quot;&gt;Update Frames&lt;/code&gt; on and XCode repositions view to someplace you didn’t expect it to, do a &lt;code class=&quot;language-text&quot;&gt;Cmd+Z&lt;/code&gt; to bring the views back to their old position without removing the constraints you added.&lt;/li&gt;
&lt;li&gt;When in doubt, check the color of the small arrow next to the view controller you are designing. Red means there are some errors in the auto layout constraints that you added. Yellow means that some frames are incorrectly positioned with respect to the constraints.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
![](https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_400/v1418058060/Screen_Shot_2014-12-08_at_18_00_15_z1s9kt.png)
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Clicking on the arrow will take you to a list of errors/warnings. You can get suggestions on how to fix it by clicking on the small circle on the right.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
![](https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_400/v1418058275/Screen_Shot_2014-12-08_at_18_03_10_vgz4ku.png)
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Deleting a constraint will not reposition your views but the layout might go into “warning” mode, indicating issues you need to resolve to make auto-layout work.&lt;/li&gt;
&lt;li&gt;When you move things around, your constraints don’t change; only view frame in IB changes. When frame in IB is actually different from calculated with layout constraints frame, IB will indicate the runtime frame of that element with yellow dotted line and the layout will be in “warning” mode.&lt;/li&gt;
&lt;li&gt;Once you have added the constraints for a view, you can update the frames of all its subviews pressing the small triangle button in the bottom after selecting the view you want to update.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
![](https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_400/v1418058476/Screen_Shot_2014-12-08_at_18_05_56_e8dfps.png)
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;If you cannot select a constraint from the Storyboard, select the view and open the Size Inspector to select the constraint from there.&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align:center&quot;&gt;
![](https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/c_scale,w_400/v1418058830/Screen_Shot_2014-12-08_at_18_13_31_kq1gpe.png)
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Animations should now be dealt in terms of auto layout constraints. This means that you should not manually touch the frame when animating. Change the constraints and call &lt;code class=&quot;language-text&quot;&gt;layoutIfNeeded&lt;/code&gt; inside the animation block. To build the constraints in code, I recommend using &lt;a href=&quot;https://github.com/Masonry/Masonry&quot;&gt;Masonry&lt;/a&gt; rather than the overly verbose defaults.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Some Tips&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;In each dimension (vertical and horizontal), each view’s position and size are defined by three values: leading space, size and trailing space. The leading and trailing spaces can be defined either in terms of a view’s superview or in relation to a sibling in the view hierarchy. Generally speaking, your layout constraints must fix two of these values so that the third one can be calculated. As a result, a standard view needs at least two constraints in each dimension for an unambiguous layout.&lt;/li&gt;
&lt;li&gt;Try to position views based on the leading and trailing spaces (or the alignment constraints) instead of pinning their heights/widths. Again, this will depend on how your views are layed out, but this is something that holds true in general for me.&lt;/li&gt;
&lt;li&gt;Auto Layout for scroll views &lt;a href=&quot;https://developer.apple.com/library/ios/technotes/tn2154/_index.html&quot;&gt;works differently&lt;/a&gt; than normal views. There is an in depth explaination about making auto layout work with scroll view in the technical note from Apple. The gist of it is 1) you will need more constraints (usually in form of pinned width/height for vertical/horizontal scrolling respectively) than with normal views because scroll view also needs to compute its content size, and 2) there should be chain of constraints that link one edge of the scroll view to its opposite edge (e.g. in the vertical dimension, there should be a &lt;code class=&quot;language-text&quot;&gt;top spacing&lt;/code&gt; constraint between your topmost subview and the scroll view, a &lt;code class=&quot;language-text&quot;&gt;bottom spacing&lt;/code&gt; constraint between the botttommost subview and the scrollview, and a chain of constraints that link the bottom edge of the topmost subview to the top edge of the bottommost subview).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I know that it sounds complex, but its not. Go try it out in XCode and I am sure you will never switch back once you understand how it works.&lt;/p&gt;
&lt;p&gt;Need some help or just want to chat? Shoot me an email at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pluralization on iOS and OS X]]></title><link>https://pulkitgoyal.in/pluralization-on-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/pluralization-on-ios</guid><pubDate>Tue, 25 Nov 2014 20:11:39 GMT</pubDate><content:encoded>&lt;p&gt;As of iOS 7 and Mac OS X 10.9 Mavericks, Foundation has the ability to specify localized strings according to pluralization and grammar rules. So no need to write code like this to deal with strings whose conjugations change based on a dynamic value anymore.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;if (count == 1) {
  return NSLocalizedString(@&amp;quot;1 Person&amp;quot;, nil);
} else {
  return [NSString stringWithFormat:NSLocalizedString(@&amp;quot;%d People&amp;quot;, nil), count];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is a new file format with &lt;code class=&quot;language-text&quot;&gt;.stringsdict&lt;/code&gt; suffix introduced. &lt;code class=&quot;language-text&quot;&gt;[NSBundle localizedStringForKey:value:table:]&lt;/code&gt; now accesses two files: &lt;code class=&quot;language-text&quot;&gt;.stringsdict&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.strings&lt;/code&gt;.  It queries the &lt;code class=&quot;language-text&quot;&gt;.stringsdict&lt;/code&gt; file first, then, &lt;code class=&quot;language-text&quot;&gt;.strings&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;.stringsdict&lt;/code&gt; file contains the original key (e.g. @“%d files are selected”) with the value as an arbitrary property list (mostly dictionary or string). When the value is a dictionary, it must contain a key for the localized format string value and its format specifier configuration dictionaries. Here’s an example:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token doctype&quot;&gt;&amp;lt;!DOCTYPE plist PUBLIC &quot;-//Apple//DTD PLIST 1.0//EN&quot; &quot;https://www.apple.com/DTDs/PropertyList-1.0.dtd&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;plist&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;1.0&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;%d files are selected&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NSStringLocalizedFormatKey&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;%#@num_files@ selected&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;num_files&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NSStringFormatSpecTypeKey&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NSStringPluralRuleType&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NSStringFormatValueTypeKey&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;d&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;zero&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;No file is&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;one&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;A file is&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;other&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;%d files are&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;plist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;p&gt;A configuration key between two @s is used to query an item in the external format configuration dictionary.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here, the &lt;code class=&quot;language-text&quot;&gt;num_files&lt;/code&gt; is the key defined in the string using the enhanced &lt;code class=&quot;language-text&quot;&gt;#&lt;/code&gt; format specifier and will be replaced depending on the passed value when using &lt;code class=&quot;language-text&quot;&gt;localizedStringWithFormat:&lt;/code&gt;. Its a bit difficult to understand at first looking at the xml file. Let us see how this plist will look like in json:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token property&quot;&gt;&quot;%d files are selected&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;NSStringLocalizedFormatKey&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;%#@num_files@ selected&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The string to format&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;num_files&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;NSStringFormatSpecTypeKey&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;NSStringPluralRuleType&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Its a plural rule&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;NSStringFormatValueTypeKey&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;d&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// We expect an integer argument&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;zero&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;No file is&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// String to use in place of `num_files` when value is zero&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;one&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;A file is&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;other&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;%d files are&quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;How to use it&lt;/strong&gt;: Just create a &lt;code class=&quot;language-text&quot;&gt;localizable.stringsdict&lt;/code&gt; file and add it to your XCode project and use it in code:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;label.text = [NSString localizedStringWithFormat:NSLocalizedString(@&amp;quot;%d files are selected&amp;quot;, @&amp;quot;%d files are selected&amp;quot;), numFilesSelected];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Note: It might not work on the simulator straight away, so you might want to try it on a device before you start pulling your hairs out!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[iOS Parse SDK Overview]]></title><link>https://pulkitgoyal.in/ios-parse-sdk-overview</link><guid isPermaLink="false">https://pulkitgoyal.in/ios-parse-sdk-overview</guid><pubDate>Fri, 14 Nov 2014 21:05:20 GMT</pubDate><content:encoded>&lt;p&gt;
  &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/56c0b00c16592cdfcb4f483011602431/302a4/parse-ios8-banner_e2pa80.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
  
  &lt;span
    class=&quot;gatsby-resp-image-wrapper&quot;
    style=&quot;position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;&quot;
  &gt;
    &lt;span
      class=&quot;gatsby-resp-image-background-image&quot;
      style=&quot;padding-bottom: 40.833333333333336%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAICAIAAAB2/0i6AAAACXBIWXMAAAsSAAALEgHS3X78AAAB1ElEQVQY00XLOW/TUADAcX+VqqCWqlAnTuzYzn05iKahCk1I09qx4/iguezY7/nZL7iHQIixGxIbQxkpAnFMMIBaBhb4KgiJxTRiQPrrv/2IZUFcrorXquL1qrgiiGs1aX1T3tgerDSUpS1l6a6yuiPHuv34rkh3O1y3ld7dSXfupe83+XaTWG0YNxrG2paxXjc26jpV15htnWyo+vHp2fsPL9991J6ekvKAN7WMKedNqWBIhYGUV3s5RSZutq2rbrXteHtGt2yuZWU7drw5PP90EUW/ouj3+ZcLyjBK4KAMtQoclBy9MDVzo1F2OCXIPUDuwZjoJSSU6gVpxc+pAdV1X3++jKI/URS9+npJj4aVYFzGZgmbeX+UBTN+5nEWJsh9QEqAklFCDRgdc+Y88+Ah1ff8Z2dvv/948+0nev4iOZ7kkZXzx5lgwiGHhQHthrQTLnBsgWFS9RjdZwzEmovzB1iwT8r2MT8OUlPAOg4LrhhMAZx0w4QbUu4/LIJED9J9yGmeMAlr9pFgHQqzkzvw8SZ6chs9qqCjGj6s4pCHAQtCxg2T//E+oESQ6sG07BUHqKShgu5nDMybc26IM1NcdHEZ+dUAFZGX83wezFknZOzwL0CPvSQezthMAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;&quot;
    &gt;
      &lt;img
        class=&quot;gatsby-resp-image-image&quot;
        style=&quot;width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;&quot;
        alt=&quot;parse ios8 banner e2pa80&quot;
        title=&quot;&quot;
        src=&quot;/static/56c0b00c16592cdfcb4f483011602431/d9199/parse-ios8-banner_e2pa80.png&quot;
        srcset=&quot;/static/56c0b00c16592cdfcb4f483011602431/8ff5a/parse-ios8-banner_e2pa80.png 240w,
/static/56c0b00c16592cdfcb4f483011602431/e85cb/parse-ios8-banner_e2pa80.png 480w,
/static/56c0b00c16592cdfcb4f483011602431/d9199/parse-ios8-banner_e2pa80.png 960w,
/static/56c0b00c16592cdfcb4f483011602431/302a4/parse-ios8-banner_e2pa80.png 1080w&quot;
        sizes=&quot;(max-width: 960px) 100vw, 960px&quot;
      /&gt;
    &lt;/span&gt;
  &lt;/span&gt;
  
  &lt;/a&gt;
    &lt;/p&gt;
&lt;p&gt;This post is intended to be a very brief introduction to the &lt;a href=&quot;https://parse.com/&quot;&gt;Parse SDK for iOS&lt;/a&gt;. It just touches the most basic points when setting up your app with Parse. Refer to the &lt;a href=&quot;https://parse.com/docs/ios_guide&quot;&gt;official guide&lt;/a&gt; for an in depth view of what’s possible with Parse.&lt;/p&gt;
&lt;p&gt;Storing data on Parse is built around the &lt;a href=&quot;https://parse.com/docs/ios/api/Classes/PFObject.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;PFObject&lt;/code&gt;&lt;/a&gt;. Each &lt;code class=&quot;language-text&quot;&gt;PFObject&lt;/code&gt; contains key-value pairs of JSON-compatible data. This data is schemaless, which means that you don’t need to specify ahead of time what keys exist on each &lt;code class=&quot;language-text&quot;&gt;PFObject&lt;/code&gt;. I highly recommend creating classes for your models derived from &lt;code class=&quot;language-text&quot;&gt;PFObject&lt;/code&gt; to avoid inconsistencies with manually handling key value pairs. To do so, just subclass &lt;code class=&quot;language-text&quot;&gt;PFObject&lt;/code&gt; and implement the &lt;code class=&quot;language-text&quot;&gt;PFSubclassing&lt;/code&gt; prototype. Define all columns on the backend as &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtDynamicResolution.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;@dynamic&lt;/code&gt;&lt;/a&gt; properties in the class like so:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;@interface QBQuote : PFObject &amp;lt;PFSubclassing&amp;gt;

// Properties on backend
@property(nonatomic, strong) NSString *text; // String column on the backend
@property(nonatomic, strong) QBImage *image; // Pointer&amp;lt;Image&amp;gt; on the backend
@property(nonatomic, strong) NSArray *tags; // Array&amp;lt;Tag&amp;gt; on the backend

// Computed properties (no need for `@dynamic` in implementation)
@property(nonatomic, readonly) BOOL favorite;

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Of course, you will need classes like &lt;code class=&quot;language-text&quot;&gt;QBTag&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;QBImage&lt;/code&gt; registered for their respective tables on the backend.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;@implementation QBQuote
@dynamic text, image, tags;

#pragma mark - Parse

+ (void)load {
    // Required to register the sub class with Parse
    [self registerSubclass];
}

+ (NSString *)parseClassName {
    // Name of class on the backend
    return @&amp;quot;Quote&amp;quot;;
}

+ (PFQuery *)query {
    PFQuery *query = [super query];

    // Include some child keys to avoid making another requests for them in the future
    [query includeKey:@&amp;quot;image&amp;quot;];
    [query includeKey:@&amp;quot;tags&amp;quot;];

    // Load from the cache if network requests fail
    query.cachePolicy = kPFCachePolicyNetworkElseCache;

    return query;
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This ia all you need to start making requests for data from the backend. I like to keep all my backend logic in the class, so I have a few more methods here for loading data from the backend. Here’s a sample implementation of loading the data using &lt;a href=&quot;https://promisekit.org/&quot;&gt;PromiseKit&lt;/a&gt; (Check out &lt;a href=&quot;https://sapandiwakar.in/promisekit-promises-for-ios/&quot;&gt;this post&lt;/a&gt; for a quick overview). Here is how you would retreive objects (using &lt;a href=&quot;https://github.com/hathway/Parse-PromiseKit&quot;&gt;Parse-PromiseKit&lt;/a&gt;):&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;#pragma mark - Backend

+ (PMKPromise *)loadWithFilterBlock:(void (^)(PFQuery *query))filterBlock page:(int)page {
    PFQuery *query = [QBQuote query];
    query.limit = kQBQuotePerPageLimit;
    query.skip = page * kQBQuotePerPageLimit;

    // Apply additional filters
    if (filterBlock) {
        filterBlock(query);
    }

    return [query promiseFindObjects];
}

+ (PMKPromise *)countWithFilterBlock:(void (^)(PFQuery *query))filterBlock {
    PFQuery *query = [QBQuote query];

    // Apply additional filters
    if (filterBlock) {
        filterBlock(query);
    }

    return [query promiseCountObjects];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Loading items is now just a simple call like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;[QBQuote loadWithFilterBlock:self.filterblock page:self.numberOfQuotes / kQBQuotePerPageLimit].then(^(NSArray *quotes) { ... }];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Need to save objects? Just update the properties, and call &lt;code class=&quot;language-text&quot;&gt;saveEventually&lt;/code&gt; and it will take care of handling the network outages and other faults. An important thing to keep in mind when creating/updating objects is the permission for the objects. Use the &lt;a href=&quot;https://parse.com/docs/ios_guide#users-security/iOS&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ACL&lt;/code&gt;&lt;/a&gt; property on &lt;code class=&quot;language-text&quot;&gt;PFObject&lt;/code&gt; to control who has access to the object. For example, to allow write access to an object by only the current user:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;quote.ACL = [PFACL ACLWithUser:[PFUser currentUser]];
[quote.ACL setPublicReadAccess:YES];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Scanning Barcodes and QR Codes with AVFoundation on iOS7+]]></title><link>https://pulkitgoyal.in/scanning-barcodes-and-qr-codes-with-avfoundation-on-ios7</link><guid isPermaLink="false">https://pulkitgoyal.in/scanning-barcodes-and-qr-codes-with-avfoundation-on-ios7</guid><pubDate>Sun, 12 Oct 2014 08:37:31 GMT</pubDate><content:encoded>&lt;p&gt;With the release of iOS 7, Apple included the ability to detect barcodes through its &lt;code class=&quot;language-text&quot;&gt;AVFoundation&lt;/code&gt; framework. It is really easy to add barcode scanning to your app without using any additional libraries. &lt;/p&gt;
&lt;p&gt;We just need to create a capture session so we can trigger the camera when needed. We set the input for the capture session to our capture device (the device camera). The output is an &lt;code class=&quot;language-text&quot;&gt;AVCaptureMetadataOutput&lt;/code&gt; object which takes care of reading the metadata from camera input. This is the core step of reading the bar codes. To see what the camera captures, we can add a preview layer to the controller’s view and attach it to the camera. Finally, to start scanning, start the session and you are done. The delegate methods will be called when a barcode is detected. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;// Find the input for default capture device
AVCaptureDevice *captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:captureDevice error:&amp;amp;error];
if (!input) {
    NSLog(@&amp;quot;%@&amp;quot;, [error localizedDescription]);
    return NO;
}

// Create a capture session and add input
self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession addInput:input];

// Add the session output
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:captureMetadataOutput];

// Configure the metadata output
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create(&amp;quot;barcodeReaderQueue&amp;quot;, NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
[captureMetadataOutput setMetadataObjectTypes:@[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeCode128Code, AVMetadataObjectTypeCode93Code, AVMetadataObjectTypeCode39Code]];

// Add a preview layer to see camera preview
self.videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self.videoPreviewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[self.videoPreviewLayer setFrame:self.previewView.layer.bounds];
[self.previewView.layer addSublayer:self.videoPreviewLayer];

// Start running the capture session
[self.captureSession startRunning];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The delegate method &lt;code class=&quot;language-text&quot;&gt;captureOutput:didOutputMetadataObjects:fromConnection:&lt;/code&gt; is called everytime a metadata object is processed. From here, we can extract the string value of the metadata object to get the barcode string. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;#pragma mark - Capture Metadata Output Objects Delegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
    if (metadataObjects != nil &amp;amp;&amp;amp; [metadataObjects count] &amp;gt; 0) {
        AVMetadataMachineReadableCodeObject *metadataObj = [metadataObjects objectAtIndex:0];
        NSString *barcodeString = metadataObj.stringValue;
        NSLog(@&amp;quot;Read barcode: %@&amp;quot;, barcodeString);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Configuring MMDrawer for Side Drawer Navigation on iOS - Part II]]></title><link>https://pulkitgoyal.in/side-drawer-navigation-for-ios-part-ii</link><guid isPermaLink="false">https://pulkitgoyal.in/side-drawer-navigation-for-ios-part-ii</guid><pubDate>Fri, 26 Sep 2014 17:20:55 GMT</pubDate><content:encoded>&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1411807754/ios7_dribbble_800x600_1x_ietinq.png&quot; style=&quot;float:right;&quot;&gt;
&lt;p&gt;In an &lt;a href=&quot;/side-drawer-navigation-for-ios&quot;&gt;earlier post&lt;/a&gt;, I presented an example of setting up the side drawer navigation pattern for iOS using Storyboards and posted an example project based on the described set up. This post expands on that set up to add some basic configuration to the side drawer.&lt;/p&gt;
&lt;p&gt;In the example app, the side drawer is first initialized when the &lt;code class=&quot;language-text&quot;&gt;DRAWER_SEGUE&lt;/code&gt; is triggered. All the configuration for &lt;code class=&quot;language-text&quot;&gt;MMDrawerController&lt;/code&gt; should be done in the &lt;code class=&quot;language-text&quot;&gt;prepareForSegue:&lt;/code&gt; for this segue. Here’s the basic configuration that we have for the drawer controller in &lt;code class=&quot;language-text&quot;&gt;PGViewController.m&lt;/code&gt; where we get the &lt;code class=&quot;language-text&quot;&gt;MMDrawerController&lt;/code&gt; instance from the segue and set a &lt;code class=&quot;language-text&quot;&gt;centerViewController&lt;/code&gt; and a &lt;code class=&quot;language-text&quot;&gt;leftDrawerViewController&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@&amp;quot;DRAWER_SEGUE&amp;quot;]) {
        MMDrawerController *destinationViewController = (MMDrawerController *) segue.destinationViewController;

        // Instantitate and set the center view controller.
        UIViewController *centerViewController = [self.storyboard instantiateViewControllerWithIdentifier:@&amp;quot;FIRST_TOP_VIEW_CONTROLLER&amp;quot;];
        [destinationViewController setCenterViewController:centerViewController];

        // Instantiate and set the left drawer controller.
        UIViewController *leftDrawerViewController = [self.storyboard instantiateViewControllerWithIdentifier:@&amp;quot;SIDE_DRAWER_CONTROLLER&amp;quot;];
        [destinationViewController setLeftDrawerViewController:leftDrawerViewController];
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Let’s add a few more configuration options to the drawer to enable gesture support for opening and closing the drawer controller, a maximum drawer width and a parallax animation.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;// Set maximum drawer width
destinationViewController.maximumLeftDrawerWidth = 254;
// Use all gestures for closing the drawer
destinationViewController.closeDrawerGestureModeMask = MMCloseDrawerGestureModeAll;
// Open the drawer only when panning the center view from the edge
destinationViewController.openDrawerGestureModeMask = MMOpenDrawerGestureModeBezelPanningCenterView;
// Set a parallax animation for opening drawer
[destinationViewController setDrawerVisualStateBlock:[MMDrawerVisualState parallaxVisualStateBlockWithParallaxFactor:5]];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;MMDrawerController&lt;/code&gt; also comes with a built in menu button. Let’s see how we can add it to a controller.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)setupLeftMenuButton {
    MMDrawerBarButtonItem * leftDrawerButton = [[MMDrawerBarButtonItem alloc] initWithTarget:self action:@selector(leftDrawerButtonPress:)];
    [self.navigationItem setLeftBarButtonItem:leftDrawerButton];
}

- (void)leftDrawerButtonPress:(id)leftDrawerButtonPress {
    [self.mm_drawerController toggleDrawerSide:MMDrawerSideLeft animated:YES completion:nil];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Starting from iOS7, the views are drawn beneath the status bar. If you want to control the style of the status bar when the side drawer is opened, all you need is to override the &lt;code class=&quot;language-text&quot;&gt;preferredStatusBarStyle&lt;/code&gt; in the controller that is set as the &lt;code class=&quot;language-text&quot;&gt;[left|right]DrawerViewController&lt;/code&gt; (&lt;code class=&quot;language-text&quot;&gt;PGSideDrawerController&lt;/code&gt; in the example project).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;#pragma mark - Status Bar
-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Multiplayer 2048 Game for iOS - Part II]]></title><link>https://pulkitgoyal.in/building-a-multiplayer-2048-game-for-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/building-a-multiplayer-2048-game-for-ios</guid><pubDate>Sun, 14 Sep 2014 14:10:41 GMT</pubDate><content:encoded>&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1399056650/placeit_fnc39p.png&quot; alt=&quot;2048 Multiplayer&quot; style=&quot;float:right; padding: 20px;&quot;&gt;
&lt;p&gt;We launched the &lt;a href=&quot;https://itunes.apple.com/us/app/2048-addictive-number-puzzle/id844505418?mt=8&amp;#x26;ign-mpt=uo%3D4&quot;&gt;2048 Game on iOS&lt;/a&gt; in April 2014. I have already written some details about why we did it and the initial launch in &lt;a href=&quot;https://pulkitgoyal.in/building-the-2048-game-for-ios&quot;&gt;a post here&lt;/a&gt;. We weren’t looking to build just another clone, there were tons of them already and we were aware of it. We wanted to push out our idea of how it can be tunrned into a multiplayer game. Here are some details about the multiplayer version and how it turned out for us (TLDR: If you just want the gist of it, it didn’t go very well or at least as well as we had planned).&lt;/p&gt;
&lt;h4&gt;The rules of multiplayer 2048&lt;/h4&gt;
&lt;p&gt;Two players share the same board and get points only for the tiles that they merge. In every turn, in addition to scoring more points, the player had to think about how to stop the other one from scoring in his next turn. Sort of like chess, sort of like the &lt;a href=&quot;https://itunes.apple.com/in/app/letterpress-word-game/id526619424?mt=8&quot;&gt;Letterpress app&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;The multiplayer version&lt;/h4&gt;
&lt;p&gt;We knew straightaway that we want to use &lt;code class=&quot;language-text&quot;&gt;GameCenter&lt;/code&gt;, Apple’s social gaming network to build the multiplayer mode. The turn based APIs matched our needs perfectly. Here are the major tasks that a turn based match needs to handle&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow the local player to join a match.&lt;/li&gt;
&lt;li&gt;Allow the local player to see the list of existing matches.&lt;/li&gt;
&lt;li&gt;Allow the local player to view the state of a match in progress.&lt;/li&gt;
&lt;li&gt;Allow the player to take a turn in the match.&lt;/li&gt;
&lt;li&gt;When a player leaves a match, set the player’s match outcome.&lt;/li&gt;
&lt;li&gt;When all the players have a match outcome set, end the match.&lt;/li&gt;
&lt;li&gt;Handle invitations and other match events.&lt;/li&gt;
&lt;li&gt;Expand your game to include exchanges.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wouldn’t bore you with too much technical details in this post. If you are curious, head over to the github and check out the code for our &lt;a href=&quot;https://github.com/Shyahi/2048-iOS&quot;&gt;open source version&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;The launch&lt;/h4&gt;
&lt;p&gt;So, all done with the turn based stuff and tests, we were heading to launch with great expectations. We thought that even if people have half of our excitement for the multiplayer version, it will still go great. So, we submit the multiplayer version to apple and after a week of wait its finally approved for App Store. We had been playing against each other the whole week waiting to finally get the chance to play against other players when the app launches. I started creating new matches against random guys and I played some intense matches with people I never knew. It was fun!&lt;/p&gt;
&lt;p&gt;So, after a few matches, we hop on to Mixpanel to see how many guys are actually trying out the multiplayer version and there was the surprise for us. Not many! Most of the guys just kept on playing the single player version and never bothered to check out the multiplayer mode. We were disappointed, we had put so much effort into this. Well, we had our moments, those who actually did try the multiplayer version enjoyed a lot.&lt;/p&gt;
&lt;h4&gt;What we learnt&lt;/h4&gt;
&lt;p&gt;We try to extract positives from every new idea that we try out. It was fun building multiplayer 2048. It was amazing to see people enjoying the game. But it was heartbreaking to see so few of them! There were a few things that we might have done differently to increase our chances.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;We didn’t put a limit on the amount of time a player could take to play his move. This allowed players to take a move and then not play for hours (or even days) which ruined the experience. We could have been omre aggressive in forcing the players to take the turn as soon as possible (e.g. by deducting time based on how long they take to copmlete the move or by giving an extra move to the second player)&lt;/li&gt;
&lt;li&gt;We were a bit late to the party. The game had already crossed its peak and there were plenty of clones out there which meant that it was really hard to find our version on the app store.&lt;/li&gt;
&lt;li&gt;This one might sound like an excuse, but the Android version of 2048 launched its own multiplayer while we were waiting for Apple to approve ours. Although, the multiplayer version in the Android app was so different from ours (I wouldn’t even call it multiplayer, 2 players played completely independent of each other on their own boards for a limited amount of time and then compared their scores when the time is over). It took some interest away from our multiplayer version and people didn’t care to notice thinking that it would be the same as the Android counterpart.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anyway, thanks for reading. It was fun. And if you like what you see, do try out the game &lt;a href=&quot;https://itunes.apple.com/us/app/2048-addictive-number-puzzle/id844505418?mt=8&amp;#x26;ign-mpt=uo%3D4&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Building the 2048 game for iOS]]></title><link>https://pulkitgoyal.in/building-the-2048-game-for-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/building-the-2048-game-for-ios</guid><pubDate>Wed, 10 Sep 2014 18:19:43 GMT</pubDate><content:encoded>&lt;p&gt;We launched the &lt;a href=&quot;https://itunes.apple.com/us/app/2048-addictive-number-puzzle/id844505418?mt=8&amp;#x26;ign-mpt=uo%3D4&quot;&gt;2048 Game on iOS&lt;/a&gt; in April 2014. We started developing the iOS version of the game (based on the initial &lt;a href=&quot;https://gabrielecirulli.github.io/2048/&quot;&gt;web based version&lt;/a&gt; from &lt;a href=&quot;https://gabrielecirulli.com/&quot;&gt;Gabriel Cirullli&lt;/a&gt;) after the game was already well pass its peak.&lt;/p&gt;
&lt;h4&gt;Why we did it?&lt;/h4&gt;
&lt;p&gt;There were enough clones already, right? Why did we build another one? Well, we had this cool idea of placing two players against each other (as in the &lt;a href=&quot;https://itunes.apple.com/in/app/letterpress-word-game/id526619424?mt=8&quot;&gt;Letterpress Game&lt;/a&gt;) on the same board, playing in turns, competing to merge as many tiles as possible. The rules were simple, two players share the same board and get points only for the tiles that they merge. In every turn, in addition to scoring more points, the player had to think about how to stop the other one from scoring in his next turn. We enjoyed this format so much that we used to play this on the traditional web version by manually noting scores and taking turns.&lt;/p&gt;
&lt;h4&gt;The first version&lt;/h4&gt;
&lt;p&gt;With the ultimate goal of building the multiplayer community of players competing against each other, we started working on the first version. We wanted to keep it simple, but we wanted to keep it native, not some webview based clone that just bluntly opens the website in the browser. It was the first game that we were going to develop, so we had no idea where to start. The board was just tiles, so we used the &lt;code class=&quot;language-text&quot;&gt;UICollectionView&lt;/code&gt; to put tiles in, added some game logic and it was done. Not yet!&lt;/p&gt;
&lt;p&gt;The default animations in the &lt;code class=&quot;language-text&quot;&gt;UICollectionView&lt;/code&gt; assumed that all the items came from just one group which means that moving an item out of a row meant that all other items in next rows change their positions. We had to use fake cells to perform the animations between items and completely disable the default &lt;code class=&quot;language-text&quot;&gt;UICollectionView&lt;/code&gt; animations. Not too small, but nothing copmlicated either. &lt;a href=&quot;https://github.com/Shyahi/2048-iOS/blob/43bb4f525a17845c7a6d0f48775bd9d342b357b9/2048/Controllers/SHGameViewController.m&quot;&gt;Take a look&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We even added a simple tilt control by using &lt;code class=&quot;language-text&quot;&gt;CoreMotion&lt;/code&gt; that allows you to move tiles by tilting the phone. Check out the &lt;code class=&quot;language-text&quot;&gt;deviceMotionDidUpdate:&lt;/code&gt; method to see the details.&lt;/p&gt;
&lt;h4&gt;The launch&lt;/h4&gt;
&lt;p&gt;We launched the first version without the multiplayer option to the AppStore in hopes of getting enough users for the app so that when the multiplayer version comes out, we would have a community of players already there to try out the game and players don’t have to wait a lot to find another player to play with. Was this move successful? Sort of. We got close to two thousand  players in a few weeks. I know that this wasn’t great, but it wasn’t too bad either considering there were already tons of clones doing the same thing already.&lt;/p&gt;
&lt;p&gt;More details about the multiplayer version &lt;a href=&quot;https://pulkitgoyal.in/building-a-multiplayer-2048-game-for-ios&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Resizing High Resolution Images on iOS Without Memory Issues]]></title><link>https://pulkitgoyal.in/resizing-high-resolution-images-on-ios-without-memory-issues</link><guid isPermaLink="false">https://pulkitgoyal.in/resizing-high-resolution-images-on-ios-without-memory-issues</guid><pubDate>Sun, 31 Aug 2014 11:11:50 GMT</pubDate><content:encoded>&lt;p&gt;If you have ever worked with user generated images in an iOS app, you would know that it is very easy to quickly spend all the memory you have which would then result in your app being terminated by the OS. In order to support high resolution images in an app, I searched around for ways to resize images on device. The easiest and the most common way is to use &lt;code class=&quot;language-text&quot;&gt;CoreGraphics&lt;/code&gt; to draw the image to a smaller rect and then convert it back to a &lt;code class=&quot;language-text&quot;&gt;UIImage&lt;/code&gt;. The problem with this approach is that it isn’t gaining you anything because for drawing the image, you are decoding it anyway which requires reading the full sized image and might crash the app.&lt;/p&gt;
&lt;p&gt;To correctly resize the image without decoding it first is to drop down a level and use the &lt;a href=&quot;https://developer.apple.com/library/ios/documentation/graphicsimaging/conceptual/ImageIOGuide/imageio_intro/ikpg_intro.html#//apple_ref/doc/uid/TP40005462-CH201-TPXREF101&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;ImageIO&lt;/code&gt;&lt;/a&gt; framework. The first thing you need with the &lt;code class=&quot;language-text&quot;&gt;ImageIO&lt;/code&gt; framework is to create an image source from an image (the image can be an existing &lt;code class=&quot;language-text&quot;&gt;UIImage&lt;/code&gt;, path to a file or even an &lt;code class=&quot;language-text&quot;&gt;ALAsset&lt;/code&gt;). Let’s see how we can resize an image when we know the local path to the image. If you have the image in some other form, all you need to change is this step (&lt;a href=&quot;https://developer.apple.com/library/ios/documentation/graphicsimaging/conceptual/ImageIOGuide/imageio_source/ikpg_source.html&quot;&gt;see this for details&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;The next step is to use the &lt;code class=&quot;language-text&quot;&gt;CGImageSourceCreateThumbnailAtIndex&lt;/code&gt; method to actually generate the thumbnail image from this source. We need to pass some options here to configure the thumbnail generation (e.g. the max pixel size). &lt;code class=&quot;language-text&quot;&gt;kCGImageSourceCreateThumbnailWithTransform&lt;/code&gt; option automatically rotates the image to the correct orientation and &lt;code class=&quot;language-text&quot;&gt;kCGImageSourceCreateThumbnailFromImageAlways&lt;/code&gt; asks the OS to create the thumbnail even if it is already present. This option is important as without it, the OS might use an existing thumbnail which can be much smaller than what you asked for.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)resizeImageAtPath:(NSString *)imagePath {
	// Create the image source
    CGImageSourceRef src = CGImageSourceCreateWithURL((__bridge CFURLRef) [NSURL fileURLWithPath:imagePath], NULL);
    // Create thumbnail options
    CFDictionaryRef options = (__bridge CFDictionaryRef) @{
            (id) kCGImageSourceCreateThumbnailWithTransform : @YES,
            (id) kCGImageSourceCreateThumbnailFromImageAlways : @YES,
            (id) kCGImageSourceThumbnailMaxPixelSize : @(640)
    };
    // Generate the thumbnail
    CGImageRef thumbnail = CGImageSourceCreateThumbnailAtIndex(src, 0, options);
    CFRelease(src);
    // Write the thumbnail at path
    CGImageWriteToFile(thumbnail, imagePath);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now that we have the &lt;code class=&quot;language-text&quot;&gt;CGImageRef&lt;/code&gt; for the small image, let’s see how we can save the image back to the path. We will use the &lt;code class=&quot;language-text&quot;&gt;CGImageDestinationAddImage&lt;/code&gt; function to write the image.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;void CGImageWriteToFile(CGImageRef image, NSString *path) {
    CFURLRef url = (__bridge CFURLRef) [NSURL fileURLWithPath:path];
    CGImageDestinationRef destination = CGImageDestinationCreateWithURL(url, kUTTypePNG, 1, NULL);
    CGImageDestinationAddImage(destination, image, nil);

    if (!CGImageDestinationFinalize(destination)) {
        NSLog(@&amp;quot;Failed to write image to %@&amp;quot;, path);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is all you need to load larger images in form of something that you can safely understand. We even tried this with a &lt;a href=&quot;https://www.jpl.nasa.gov/spaceimages/details.php?id=PIA15817&quot;&gt;6019×6019 image from NASA&lt;/a&gt; without any memory problems.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using Grunt to Auto Upload Files to Android]]></title><link>https://pulkitgoyal.in/using-grunt-to-auto-upload-files-to-android</link><guid isPermaLink="false">https://pulkitgoyal.in/using-grunt-to-auto-upload-files-to-android</guid><pubDate>Tue, 19 Aug 2014 18:33:50 GMT</pubDate><content:encoded>&lt;p&gt;Grunt is a JavaScript task runner. It is being used heavily for web development to automate repititive tasks like minification, compilation, unit testing, linting, etc. After you’ve configured it, a task runner can do most of that mundane work for you—and your team—with basically zero effort.&lt;/p&gt;
&lt;p&gt;For a recent project, I had to repeatedly upload some files to my Android device whenever some changes were made on the code base. Being familiar with  &lt;a href=&quot;https://developer.android.com/tools/help/adb.html&quot;&gt;adb&lt;/a&gt;, it was my immediate choice to upload files. Just a simple command &lt;code class=&quot;language-text&quot;&gt;adp push&lt;/code&gt; and your files are on the device in no time. Since I was already working with Grunt on the project with a &lt;a href=&quot;https://github.com/gruntjs/grunt-contrib-watch&quot;&gt;watch&lt;/a&gt; task configured to identify when some files change, it was really simple to add another task to run the command to upload files.&lt;/p&gt;
&lt;p&gt;First you would need the &lt;a href=&quot;https://github.com/sindresorhus/grunt-shell&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;grunt-shell&lt;/code&gt;&lt;/a&gt; task to execute shell commands. Then, just put in the configuration for shell task and you are ready to go.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;shell &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  sync_android&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    command&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&amp;lt;%= adbPath %&gt; push &apos;path/to/local/directory&apos; &apos;&amp;lt;%= pathOnDevice %&gt;&apos;&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The variables &lt;code class=&quot;language-text&quot;&gt;adbPath&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;pathOnDevice&lt;/code&gt; are defined in grunt config as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;config&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  adbPath&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;/Applications/Android\\ Studio.app/sdk/platform-tools/adb&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  pathOnDevice&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; grunt&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;android_path&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&amp;lt;default/path/on/device&gt;&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, just run the task from command line: &lt;code class=&quot;language-text&quot;&gt;grunt shell:sync_android [--android_path=]&lt;/code&gt; or wire with &lt;code class=&quot;language-text&quot;&gt;watch&lt;/code&gt; to auto upload files.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Retrieving Videos from YouTube Channel in Objective-C API v3]]></title><link>https://pulkitgoyal.in/retrieving-videos-from-youtube-channel-in-objective-c-using-v3-of-the-api</link><guid isPermaLink="false">https://pulkitgoyal.in/retrieving-videos-from-youtube-channel-in-objective-c-using-v3-of-the-api</guid><pubDate>Tue, 05 Aug 2014 15:58:01 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://developers.google.com/youtube/v3/&quot;&gt;The YouTube Data API (v3)&lt;/a&gt; lets you incorporate YouTube functionality into your own application. You can use the API to fetch search results and to retrieve, insert, update, and delete resources like videos or playlists.&lt;/p&gt;
&lt;p&gt;This blog post gives a quick overview of sending queries using the &lt;a href=&quot;https://code.google.com/p/google-api-objectivec-client/&quot;&gt;Obj-C Library&lt;/a&gt;. Lets see how to get all videos for a channel with known id. First, we will send a &lt;code class=&quot;language-text&quot;&gt;list channel&lt;/code&gt; query with our channel identifier to load the channel info. Then we execute a &lt;code class=&quot;language-text&quot;&gt;list playlist items&lt;/code&gt; query to find all videos in the playlists. Here’s some code: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objc&quot;&gt;&lt;pre class=&quot;language-objc&quot;&gt;&lt;code class=&quot;language-objc&quot;&gt;- (void)loadChannels {
    GTLQueryYouTube *channelsQuery = [GTLQueryYouTube queryForChannelsListWithPart:@&amp;quot;id,snippet,brandingSettings,contentDetails,invideoPromotion,statistics,status,topicDetails&amp;quot;];
    channelsQuery.identifier = @&amp;quot;&amp;lt;CHANNEL_IDENTIFIER&amp;gt;&amp;quot;;

    [self.youTubeService executeQuery:channelsQuery completionHandler:^(GTLServiceTicket *ticket, GTLYouTubeChannelListResponse *channelListResponse, NSError *error) {
        if (error == nil) {
            if (channelListResponse.items.count &amp;gt; 0) {
                GTLYouTubeChannel *channel = channelListResponse.items.firstObject;
                NSLog(@&amp;quot;Got youtube channel - %@&amp;quot;, channel);
                [self loadPlaylistsForChannel:channel];
            } else {
                NSLog(@&amp;quot;Cannot find channels with id %@&amp;quot;, channelsQuery.identifier);
            }

        } else {
            NSLog(@&amp;quot;Cannot get youtube channels - %@&amp;quot;, error);
        }
    }];
}

- (void)loadPlaylistsForChannel:(GTLYouTubeChannel *)channel {
    NSString *playlistId = channel.contentDetails.relatedPlaylists.uploads;
    if (playlistId) {
        GTLQueryYouTube *playlistsQuery = [GTLQueryYouTube queryForPlaylistItemsListWithPart:@&amp;quot;id,snippet,contentDetails,status&amp;quot;];
        playlistsQuery.playlistId = playlistId;
        [self.youTubeService executeQuery:playlistsQuery completionHandler:^(GTLServiceTicket *ticket, GTLYouTubePlaylistItemListResponse *playlistListResponse, NSError *error) {
            if (error == nil) {
                if (playlistListResponse.items.count &amp;gt; 0) {
                    self.playlistItems = playlistListResponse.items;
                    [self.swipeView reloadData];
                    for (GTLYouTubePlaylistItem *playlistItem in playlistListResponse.items) {
                        NSLog(@&amp;quot;Got youtube playlist items - %@&amp;quot;, playlistItem);
                    }
                    [self loadVideoForPlaylistItem:playlistListResponse.items.firstObject];
                } else {
                    NSLog(@&amp;quot;Cannot find playlists items with playlist id %@&amp;quot;, playlistId);
                }
            } else {
                NSLog(@&amp;quot;Cannot get youtube playlist items - %@&amp;quot;, error);
            }
        }];
    } else {
        NSLog(@&amp;quot;Playlist &amp;#39;uploads&amp;#39; not found for channel.&amp;quot;);
    }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are several queries available from the API. For the complete list, head over to the &lt;a href=&quot;https://developers.google.com/youtube/v3/docs/&quot;&gt;API Reference&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[iOS CoreData Overview]]></title><link>https://pulkitgoyal.in/coredata-overview</link><guid isPermaLink="false">https://pulkitgoyal.in/coredata-overview</guid><pubDate>Sat, 21 Jun 2014 18:06:35 GMT</pubDate><content:encoded>&lt;p&gt;This post is intended to be a very brief introduction to Core Data. It just touches the most important points when setting up a core data stack.&lt;/p&gt;
&lt;p&gt;The schema for the database is defined in &lt;code class=&quot;language-text&quot;&gt;my-project.xcdatamodeld&lt;/code&gt;. This is where you tell CoreData what entities to expect and what attributes and relationships go in each entity. The .h and .m files for the entities can be generated automatically from the schema using XCode (&lt;a href=&quot;https://www.raywenderlich.com/934/core-data-tutorial-for-ios-getting-started#autogeneratingmodelfiles&quot;&gt;some details here&lt;/a&gt;). Just open &lt;code class=&quot;language-text&quot;&gt;.xcdatamodel&lt;/code&gt;file, click on the entity, and go to &lt;code class=&quot;language-text&quot;&gt;File&lt;/code&gt;-&gt;&lt;code class=&quot;language-text&quot;&gt;New&lt;/code&gt;-&gt;&lt;code class=&quot;language-text&quot;&gt;File&lt;/code&gt;. Select the &lt;code class=&quot;language-text&quot;&gt;Core Data\NSManagedObject subclass&lt;/code&gt;, and click Next, and then click Create again on the following view.&lt;/p&gt;
&lt;p&gt;Its better to not play with these because they will be overwritten whenever you make changes in the schema and re-generate the files. To add custom methods and properties to these entities, I usually prefer creating categories on the entity (&lt;code class=&quot;language-text&quot;&gt;MyEntity+Extensions.h,m&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&quot;https://github.com/magicalpanda/MagicalRecord&quot;&gt;MagicalRecord&lt;/a&gt; to perform CoreData requests. We could do it using the native CoreData APIs, but MagicalRecord makes it a lot easier and intuitive. Fetching from the database is done with the &lt;code class=&quot;language-text&quot;&gt;MR_&lt;/code&gt; methods on the entity. e.g. &lt;code class=&quot;language-text&quot;&gt;[MyEntity MR_findAll]&lt;/code&gt; will return an array of all news items in the database. Filtering can be done with predicates (e.g. this fetches all news for the given date).&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Introducing Multiplayer mode for 2048]]></title><link>https://pulkitgoyal.in/introducing-multiplayer-mode-for-2048</link><guid isPermaLink="false">https://pulkitgoyal.in/introducing-multiplayer-mode-for-2048</guid><pubDate>Sat, 03 May 2014 09:27:49 GMT</pubDate><content:encoded>&lt;p&gt;Today, we&amp;#x2019;re introducing a completely new experience for enjoying 2048 game on your iPhone. With the 2nd version of our &lt;a href=&quot;https://itunes.apple.com/us/app/2048-addictive-number-puzzle/id844505418?mt=8&amp;amp;ign-mpt=uo%3D4&quot;&gt;2048 game&lt;/a&gt;, you will now see that there is an option to play against other players in a multiplayer match. We have put a lot of thought and time in trying to come up with a good gameplay experience for this multiplayer mode.&amp;#xA0;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;&lt;span&gt;&lt;img alt=&quot;image&quot; src=&quot;https://31.media.tumblr.com/470cc5cac5418c89f904fe56e1402f45/tumblr_inline_n2w2hlyaBq1s9nh4n.png&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;You can choose to start a new multiplayer match with a randomly chosen opponent or invite your friends to play with. The game is played on a single board shared between both the players who take turns to play. The score of a player is computed by the number on the tiles that the player merges when playing his turn. The game ends when there are no moves remaining or someone reaches the 2048 tile. At this point, the player with the highest score wins the game.&amp;#xA0;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;&lt;a class=&quot;btn-store&quot; href=&quot;https://itunes.apple.com/us/app/2048-addictive-number-puzzle/id844505418?mt=8&amp;amp;uo=4&quot; id=&quot;btn-appstore-header&quot;&gt; &lt;img alt=&quot;2048 on App Store&quot; src=&quot;https://2048.shyahi.com/images/Download_on_the_App_Store_Badge_US-UK_135x40.svg&quot; width=&quot;225px&quot;&gt; &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;So what are you waiting for, get the app from the AppStore now and start competing with your friends. We promise, it will be fun!&amp;#xA0;&lt;/p&gt;
&lt;p align=&quot;center&quot;&gt;&lt;img alt=&quot;image&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1399056650/placeit_fnc39p.png&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is cross posted from &lt;a href=&quot;https://blog.shyahi.com/post/84595741291/introducing-multiplayer-mode-for-2048&quot;&gt;The Shyahi Blog&lt;/a&gt;. If you like what you see, I encourage you to sign up for the &lt;a href=&quot;https://pulkitgoyal.in/rss/&quot;&gt;RSS feed&lt;/a&gt; or follow me on &lt;a href=&quot;https://twitter.com/pulkit110&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Pull to Refresh with iOS 7 style cover image behind Navigation Bar]]></title><link>https://pulkitgoyal.in/pull-to-refresh-with-ios-7-style-cover-image-behind-navigation-bar</link><guid isPermaLink="false">https://pulkitgoyal.in/pull-to-refresh-with-ios-7-style-cover-image-behind-navigation-bar</guid><pubDate>Tue, 11 Mar 2014 06:21:24 GMT</pubDate><content:encoded>&lt;p&gt;A very common interface design that we have started seeing with iOS7 apps is having a big cover photo on the top of table views which extends all the way up to the status bar. Here’s an &lt;a href=&quot;https://drbl.in/jLMs&quot;&gt;example&lt;/a&gt;. However, by default, iOS adds an inset to the scroll views so that the content starts from below the top layout guide. Its easy to put everything back to top, though. All we need is to set the &lt;code class=&quot;language-text&quot;&gt;contentInset&lt;/code&gt; of tableview to &lt;code class=&quot;language-text&quot;&gt;UIEdgeInsetsMake(0, 0, 0, 0)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lets try to put a refresh control to our tableview now. I like to use a &lt;code class=&quot;language-text&quot;&gt;UIViewController&lt;/code&gt; instead of a &lt;code class=&quot;language-text&quot;&gt;UITableViewController&lt;/code&gt; to have more control over the views. Here’s a hack to make the refresh control work with &lt;code class=&quot;language-text&quot;&gt;UIViewController&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;// Add pull to refresh control.
UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.tableView;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(doRefresh) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now try pulling the tableview down. So, we have the refresh control, but it is hidden behind the navbar. The pull to refresh control starts from the content inset for the tableview and we already set it to &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; to have our cover image nicely fit behind the navbar. Time for another quick hack to get this to work. We need to offset the content in the header view by 64 pixels (the length of the top layout guide) and reset the top content inset for tableview to 64 pixels so that the cover image starts from behind the navigation bar and the pull to refresh from below.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@&amp;quot;7.0&amp;quot;)) {
        self.tableView.contentInset = UIEdgeInsetsMake(self.topLayoutGuide.length, 0, 0, 0); // This is the default and might not be necessary
        self.headerContainerViewConstraint.constant = -self.topLayoutGuide.length;
        self.tableView.tableHeaderView.frame = CGRectMake(self.tableView.tableHeaderView.frame.origin.x, self.tableView.tableHeaderView.frame.origin.y, self.tableView.tableHeaderView.frame.size.width, self.tableView.tableHeaderView.frame.size.height - self.topLayoutGuide.length);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Handling authenticated activities after logout [Android]]]></title><link>https://pulkitgoyal.in/handling-authenticated-activities-after-logout-android</link><guid isPermaLink="false">https://pulkitgoyal.in/handling-authenticated-activities-after-logout-android</guid><pubDate>Sun, 23 Feb 2014 08:04:54 GMT</pubDate><content:encoded>&lt;p&gt;Handling authenticated users is a very common scenario in a lot of applications. In such a scenario, you might have some activities which should be accessible to only authenticated users and there might be serveral of these activities open in the stack. How do you handle log out from an arbitrary stage in the app when you might have several activities that depend on authentication pushed on the back stack?&lt;/p&gt;
&lt;p&gt;One way is to send the user to a “Login” activity with its flag set to &lt;a href=&quot;https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;FLAG_ACTIVITY_CLEAR_TOP&lt;/code&gt;&lt;/a&gt; on log out which will clear all activities in the back stack upto the login activity. But this wouldn’t work if you can have saved sessions between app restarts where there might not even be an existing login activity when the user logs out.&lt;/p&gt;
&lt;p&gt;Another option would be to check the log in status in &lt;code class=&quot;language-text&quot;&gt;onCreate&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;finish()&lt;/code&gt; the activity if the user is not logged in. Seems hacky, doesn’t it?&lt;/p&gt;
&lt;p&gt;Lets think about what we want to do here. We want multiple activities to be able to be notified as soon as the user logs out. This is the task for a &lt;a href=&quot;https://developer.android.com/reference/android/content/BroadcastReceiver.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;BroadcastReceiver&lt;/code&gt;&lt;/a&gt;. Basically we need to brodcast a logout message to all our Activities that need to stay under a logged-in status. We can use the &lt;a href=&quot;https://developer.android.com/reference/android/content/Context.html#sendBroadcast(android.content.Intent)&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;sendBroadcast&lt;/code&gt;&lt;/a&gt; and install a &lt;code class=&quot;language-text&quot;&gt;BroadcastReceiver&lt;/code&gt; in all our Actvities.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// After logging out&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt; broadcastIntent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
broadcastIntent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;com.package.ACTION_LOGOUT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;sendBroadcast&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;broadcastIntent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And for all the activities that require authentication, register a receiver in onCreate. Make sure to also call &lt;code class=&quot;language-text&quot;&gt;LocalBroadcastManager.getInstance(this).unregisterReceiver()&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;onDestroy()&lt;/code&gt; so that we don’t receive any more broadcasts.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Bundle&lt;/span&gt; savedInstanceState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onCreate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;savedInstanceState&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token class-name&quot;&gt;IntentFilter&lt;/span&gt; intentFilter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IntentFilter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    intentFilter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addAction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;com.package.ACTION_LOGOUT&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;LocalBroadcastManager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerReceiver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;BroadcastReceiver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onReceive&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt; intent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token class-name&quot;&gt;Log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;onReceive&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Logout in progress&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token comment&quot;&gt;//At this point we should start the login activity and finish this one.&lt;/span&gt;
            &lt;span class=&quot;token function&quot;&gt;finish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; intentFilter&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Add params to Ember Data's RESTAdapter AJAX Requests]]></title><link>https://pulkitgoyal.in/add-params-ember-datas-restadapter-ajax-requests</link><guid isPermaLink="false">https://pulkitgoyal.in/add-params-ember-datas-restadapter-ajax-requests</guid><pubDate>Sun, 26 Jan 2014 21:55:17 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://github.com/emberjs/data&quot;&gt;Ember Data&lt;/a&gt; is a persistence layer for &lt;a href=&quot;https://www.emberjs.com/&quot;&gt;Ember.Js&lt;/a&gt;. Ember Data is a library that integrates tightly with Ember.js to make it easy to retrieve records from a server, cache them for performance, save updates back to the server, and create new records on the client.&lt;/p&gt;
&lt;p&gt;Ember Data makes it really simple to communicate with a RESTful JSON API by automatically creating appropriate urls for REST API calls and serializing/desserialzing parameters as required. However, for certain tasks, it is important to be able to customize certain things that Ember Data automates for you. For example, you might want to add some parameters to all the requests that you send through Ember Data in order to authenticate the user. As with everything else in Ember, you could do it with very little extra code. Just override the &lt;code class=&quot;language-text&quot;&gt;ajax&lt;/code&gt; method in &lt;code class=&quot;language-text&quot;&gt;RESTAdapter&lt;/code&gt; to add your params and you are done.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RESTAdapter &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RESTAdapter&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Scope all ajax calls.&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;ajax&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hash&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Ember&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isEmpty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; hash &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Ember&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isEmpty&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; hash&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    hash&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;access_token &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;accessToken&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Add an access token param.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; hash&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Building RESTful iOS apps using RestKit]]></title><link>https://pulkitgoyal.in/building-restful-ios-apps-restkit</link><guid isPermaLink="false">https://pulkitgoyal.in/building-restful-ios-apps-restkit</guid><pubDate>Tue, 24 Dec 2013 20:02:10 GMT</pubDate><content:encoded>&lt;p&gt;RestKit is an Objective-C framework for iOS that aims to make interacting with RESTful web services simple, fast and fun. It combines a clean, simple HTTP request/response API with a powerful object mapping system that reduces the amount of code you need to write to get stuff done.&lt;/p&gt;
&lt;p&gt;This post is not about getting started with RestKit. There are several excellent &lt;a href=&quot;https://github.com/RestKit/RestKit/#overview&quot;&gt;posts&lt;/a&gt; &lt;a href=&quot;https://mobile.tutsplus.com/tutorials/iphone/restkit_ios-sdk/&quot;&gt;already&lt;/a&gt; &lt;a href=&quot;https://github.com/RestKit/RKGist/blob/master/TUTORIAL.md&quot;&gt;available&lt;/a&gt; that talk about it. This is about how you can structure your apps to better leverage the RestKit functionality and keep the code maintainable and easy to follow.&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;RKRouter&lt;/code&gt; is something that isn’t described in great detail in the existing guides. It is also something that is very powerful and is great to put together all the routes for your REST requests. An &lt;code class=&quot;language-text&quot;&gt;RKRouter&lt;/code&gt; instance is responsible for generating &lt;code class=&quot;language-text&quot;&gt;NSURL&lt;/code&gt; objects with a given base URL and a route set. It is used to centralize the knowledge about the URL’s that are used by the application.&lt;/p&gt;
&lt;p&gt;URL’s can be generated by the router in three ways:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By name.&lt;/strong&gt; Named routes link a symbolic name with a path and an HTTP request method. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;By object.&lt;/strong&gt; Routes can be defined by class and HTTP request method. When a URL is requested from the router for an object, the router will identify the most appropriate route for the object and instantiate an NSURL with the route’s path pattern and interpolate it against the object.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;By object relationship.&lt;/strong&gt; Routes can be defined for relationships to other objects. When a URL is requested from the router for a relationship, the router will retrieve the appropriate route for the relationship from the route set and interpolate the route’s path pattern against the source object.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let see how we can organise our app to leverage the capabilities of RKRouter. We create an interface for each of our model that we expect in the response from our RESTful API.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;@interface GHUser

@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSString* login;
@property (nonatomic, retain) NSString* email;
@property (nonatomic, retain) NSArray* repositories

+ (RKObjectMapping *) responseMapping;

@end

@implementation GHUser

+ (NSDictionary*)elementToPropertyMappings {
  return @{
    @&amp;quot;name&amp;quot;: @&amp;quot;name&amp;quot;,
    @&amp;quot;login&amp;quot;: @&amp;quot;login&amp;quot;,
    @&amp;quot;email&amp;quot;: @&amp;quot;email&amp;quot;,
  };
}

+ (RKObjectMapping *) responseMapping {
  // Create an object mapping.
  RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[GHUser class]];
  [mapping addAttributeMappingsFromDictionary:[GHUser elementToPropertyMappings]];

  // Add some relation mappings (if any.)
  [mapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@&amp;quot;repositories&amp;quot; toKeyPath:@&amp;quot;repositories&amp;quot; withMapping:[GMRepository responseMapping]]];

  return mapping;
}

@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We want to separate the object mapping for each of the objects into their own class rather than putting them at one place where we declare the routes in order to make this manageable. We do this by creating a static method called &lt;code class=&quot;language-text&quot;&gt;responseMapping&lt;/code&gt; on each of our model which we can then use to get the mapping that we need. If you also need to send some objects as request body, you can declare a method like &lt;code class=&quot;language-text&quot;&gt;requestMapping&lt;/code&gt; to create a mapping that can be used in a &lt;code class=&quot;language-text&quot;&gt;RKRequestDescriptor&lt;/code&gt;. The simplest implementation of the &lt;code class=&quot;language-text&quot;&gt;requestMapping&lt;/code&gt; could be &lt;code class=&quot;language-text&quot;&gt;return [[GHUser responseMapping] inverseMapping];&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;With this done, we can start creating some routes. Let’s have a interface called RestClient that will manage all the routes and also a shared object manager that holds everything.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;// -- RestClient.h -- //

// Declare constants.
extern NSString *const kRestClientListUsersRouteName;

// Interface declaration.
@interface RestClient : NSObject

    + (instancetype)sharedClient;

@end

// -- RestClient.m -- //

// Define constants.
NSString *const kRestClientListUsersRouteName = @&amp;quot;LIST_USERS_ROUTE&amp;quot;;

// Interface implementation.
@implementation RestClient

static RestClient *sharedClient = nil;

- (id)init {
    self = [super init];
    if (self) {
        [self initializeObjectManagers];

        // Set shared manager if nil
        if (nil == sharedClient) {
            [RestClient setSharedClient:self];
        }
    }

    return self;
}

- (void)initializeObjectManagers {
    // Uncomment below to enable rest kit logging.
    // RKLogConfigureByName(&amp;quot;RestKit/Network&amp;quot;, RKLogLevelTrace);

    // Configure the object manager.
    RKObjectManager *objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:@&amp;quot;https://github.com/&amp;quot;]];
    objectManager.requestSerializationMIMEType = RKMIMETypeJSON;
    [RKObjectManager setSharedManager:objectManager];

    // -- Declare routes -- //

    // List users route. We create a named route here.
    RKObjectMapping *userMapping = [GHUser responseMapping];
    RKResponseDescriptor *listUsersResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping method:RKRequestMethodGET pathPattern:@&amp;quot;api/v2/users&amp;quot; keyPath:@&amp;quot;users&amp;quot; statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    [objectManager addResponseDescriptor:listUsersResponseDescriptor];
    [objectManager.router.routeSet addRoute:[RKRoute routeWithName:kRestClientListUsersRouteName pathPattern:@&amp;quot;api/v2/users&amp;quot; method:RKRequestMethodGET]];

    // Get user by name route. We create a class route here.
    RKResponseDescriptor *userResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping method:RKRequestMethodGET pathPattern:@&amp;quot;api/v2/users/:name&amp;quot; keyPath:@&amp;quot;user&amp;quot; statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    [objectManager addResponseDescriptor:userResponseDescriptor];
    [objectManager.router.routeSet addRoute:[RKRoute routeWithClass:[GMuser class] pathPattern:@&amp;quot;api/v2/users/:name&amp;quot; method:RKRequestMethodGET]];

    // Create user route. We want to send the user in the body of POST request.
    RKObjectMapping *userRequestMapping = [GMUser requestMapping];
    RKRequestDescriptor *userRequestDescriptor = [RKRequestDescriptor requestDescriptorWithMapping:userRequestMapping objectClass:[GMUser class] rootKeyPath:@&amp;quot;user&amp;quot; method:RKRequestMethodPOST];
    [objectManager addRequestDescriptor:userRequestDescriptor];
    RKResponseDescriptor *createUserResponseDescriptor = [RKResponseDescriptor responseDescriptorWithMapping:userMapping method:RKRequestMethodPOST pathPattern:@&amp;quot;api/v2/users&amp;quot; keyPath:@&amp;quot;user&amp;quot; statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
    [objectManager addResponseDescriptor:createUserResponseDescriptor];
    [objectManager.router.routeSet addRoute:[RKRoute routeWithClass:[GMUser class] pathPattern:@&amp;quot;api/v2/users&amp;quot; method:RKRequestMethodPOST]];
}

#pragma mark - Shared Client
+ (void)setSharedClient:(RestClient *)client {
    sharedClient = client;
}

+ (instancetype)sharedClient {
    return sharedClient;
}
@end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you see, we add up all the routes for our REST requests in our rest client. If we want to separate things further, we might create a new static method in the GHUser interface that builds up the routes specific to the user. Anyway, after this, all we need to do is to initialise the rest client to store all the routes in. You can do this in you AppDelegate like so: &lt;code class=&quot;language-text&quot;&gt;[[RestClient alloc] init];&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now, executing the requests is a simple call to the appropriate RKObjectManager method. e.g. To list all the users,&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;// Get list of users.
[[RKObjectManager sharedManager] getObjectsAtPathForRouteNamed:kRestClientListUsersRouteName
                                                            object:nil
                                                        parameters:parameters
                                                           success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                                               // Do something with mappingResult.array.
                                                           }
                                                           failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                                               // Do something.
                                                           }];

// Get a user by user name.
[[RKObjectManager sharedManager] getObject:[GHUser userWithName:@&amp;quot;pulkit110&amp;quot;] path:nil parameters:nil
                                   success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
                                       // Do something with [mappingResult firstObject]
                                   }
                                   failure:^(RKObjectRequestOperation *operation, NSError *error) {
                                       // Do something
                                   }];

// Create a new user.
[[RKObjectManager sharedManager] postObject:user path:nil parameters:nil
                                    success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {

                                    }
                                    failure:^(RKObjectRequestOperation *operation, NSError *error) {

                                    }&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[How to Implement Side Drawer Navigation for iOS]]></title><link>https://pulkitgoyal.in/side-drawer-navigation-for-ios</link><guid isPermaLink="false">https://pulkitgoyal.in/side-drawer-navigation-for-ios</guid><pubDate>Mon, 23 Dec 2013 16:11:15 GMT</pubDate><content:encoded>&lt;p&gt;The slide-out design pattern lets developers add permanent navigation to their apps without taking up valuable screen real estate. The user can choose to reveal the navigation at any time, while still seeing their current context.&lt;/p&gt;
&lt;p&gt;Its really easy to add one in your apps with wonderful libraries like &lt;a href=&quot;https://github.com/mutualmobile/MMDrawerController&quot;&gt;MMDrawerController&lt;/a&gt; around. But most of the examples around just show an overly simplified view without any hints on how to structure your code for such a navigation pattern. This post tries to introduce an intuitive and easy to maintain structure for integrating &lt;code class=&quot;language-text&quot;&gt;MMDrawerController&lt;/code&gt; in an app with multiple contexts using Storyboard. Lets say, we want to have a root controller that does something and then we navigate to the drawer controller. The DrawerController is an instance of &lt;code class=&quot;language-text&quot;&gt;MMDrawerController&lt;/code&gt; and wraps a navigation drawer, and a center view controller. We will create everything in the Storyboard and use &lt;code class=&quot;language-text&quot;&gt;[self.storyboard instantiateViewControllerWithIdentifier:identifier]&lt;/code&gt; to instantiate the view controllers properly from there into our drawer controller’s &lt;code class=&quot;language-text&quot;&gt;leftDrawerViewController&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;centerViewController&lt;/code&gt;. Here’s how our Storyboard looks like:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_643,w_1024/v1392235436/Screen_Shot_2013-12-23_at_16_44_24-15_feavvg.png&quot; alt=&quot;MMDrawerController Example Storyboard&quot;&gt;&lt;/p&gt;
&lt;p&gt;Notice that we assign a storyboard identifier in the &lt;code class=&quot;language-text&quot;&gt;Identity Inspector&lt;/code&gt; so that we can instantiate the view controller from the Storyboard. Let’s assign identifier &lt;code class=&quot;language-text&quot;&gt;FIRST_TOP_VIEW_CONTROLLER&lt;/code&gt; to the navigation controller of &lt;code class=&quot;language-text&quot;&gt;FirstViewController&lt;/code&gt; so that we can use it as a center view controller. Now, all we need to do is to perform the segue to Drawer View Controller and instantiate the left and center controllers in the &lt;code class=&quot;language-text&quot;&gt;prepareForSegue:&lt;/code&gt; and set the controllers to the drawer controller like so:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  if ([segue.identifier isEqualToString:@&amp;quot;DRAWER_SEGUE&amp;quot;]) {
    MMDrawerController *destinationViewController = (MMDrawerController *)segue.destinationViewController;

    // Instantitate and set the center view controller.
    UIViewController *centerViewController = [self.storyboard instantiateViewControllerWithIdentifier:@&amp;quot;FIRST_TOP_VIEW_CONTROLLER&amp;quot;];
    [destinationViewController setCenterViewController: centerViewController];

    // Instantiate and set the left drawer controller.
    UIViewController *leftDrawerViewController = [self.storyboard instantiateViewControllerWithIdentifier:@&amp;quot;SIDE_DRAWER_CONTROLLER&amp;quot;];
    [destinationViewController setLeftDrawerViewController: leftDrawerViewController];
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we have a basic setup where we can segue to a navigation controller and instantiate the drawer and center controllers from the Storyboard. Now, how do we handle a user click on the the side drawer items to navigate to another controller in the center? Its simple! Just instantiate another view controller (like &lt;code class=&quot;language-text&quot;&gt;[self.storyboard instantiateViewControllerWithIdentifier:@&amp;quot;SECOND_TOP_VIEW_CONTROLLER&amp;quot;]&lt;/code&gt;) and set it as the center view controller for the drawer controller. You can access the drawer controller form any of your view controller using &lt;code class=&quot;language-text&quot;&gt;self.mm_drawerController&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;[self.mm_drawerController setCenterViewController:[self.storyboard instantiateViewControllerWithIdentifier:@&amp;quot;SECOND_TOP_VIEW_CONTROLLER&amp;quot;] withCloseAnimation:YES completion:nil];&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just add more outlets from the side navigation drawer, instantiate new center controllers and set to the drawer controller. Its that simple to add a fully functional navigation drawer in your app. Now, you can keep on adding more controllers to each of you individual section just like you would in a normal app by creating more segues.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/pulkit110/SideDrawerExample-iOS&quot;&gt;Here’s an implementation&lt;/a&gt; using this approach.&lt;/p&gt;
&lt;p&gt;If you need a developer for your project, feel free to contact me at &lt;a href=&quot;mailto:pulkit110@gmail.com&quot;&gt;pulkit110@gmail.com&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Uploading Objects to Amazon S3 Using Pre-Signed URLs]]></title><link>https://pulkitgoyal.in/uploading-objects-amazon-s3-pre-signed-urls</link><guid isPermaLink="false">https://pulkitgoyal.in/uploading-objects-amazon-s3-pre-signed-urls</guid><pubDate>Fri, 25 Oct 2013 19:16:03 GMT</pubDate><content:encoded>&lt;p&gt;Amazon S3 is storage for the Internet. But you don&apos;t always want to give away the security credentials to anyone who wants to see/upload something on your bucket. This is where pre-signed urls come in. Anyone with valid security credentials can create a pre-signed URL. However, in order to successfully access an object, the pre-signed URL must be created by someone who has permission to perform the operation that the pre-signed URL is based upon. A pre-signed URL gives you access to the object identified in the URL.&lt;/p&gt;
&lt;p&gt;I rencently came across the need to upoad an object to Amazon S3 using a pre signed url from an iOS app. There are some examples for Java, .NET and Ruby already &lt;a href=&quot;https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html&quot;&gt;available from Amazon&lt;/a&gt;. However, I couldn&apos;t find something similar for iOS. Here&apos;s an example on how you can upload an image to S3 using an presigned url from an iOS app. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;-(void) uploadImage:(UIImage *)image atUrl:(NSString *)url {

  // Upload the image.
  NSData *imageData = UIImageJPEGRepresentation(image, 0.7);
  AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:@&amp;quot;BASE_URL&amp;quot;]; // Initialize the client with some base url.

  // Create URL request.
  NSURL *requestURL = [NSURL URLWithString:[url stringByDecodingURLFormat]];
  NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
  [request setHTTPMethod:@&amp;quot;PUT&amp;quot;];
  [request setValue:@&amp;quot;image/jpeg&amp;quot; forHTTPHeaderField:@&amp;quot;Content-Type&amp;quot;];
  [request setHTTPBody:imageData];
  [request setValue:[NSString stringWithFormat:@&amp;quot;%d&amp;quot;, [imageData length]] forHTTPHeaderField:@&amp;quot;Content-Length&amp;quot;];
  [request setValue:@&amp;quot;public-read&amp;quot; forHTTPHeaderField:@&amp;quot;x-amz-acl&amp;quot;];
  [request setValue:@&amp;quot;iPhone-OS/6.0 fr_FR NE&amp;quot; forHTTPHeaderField:@&amp;quot;User-Agent&amp;quot;];
  [request setURL:requestURL];

  // Create the request operation.
  AFHTTPRequestOperation *requestOperation = [client HTTPRequestOperationWithRequest:request
                                                                             success:^(AFHTTPRequestOperation *operation, id responseObject) {
                                                                                 // Do something after successful upload.
                                                                             }
                                                                             failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                                                                                 // Upload failed.
                                                                             }];

  [requestOperation setUploadProgressBlock:^(NSUInteger bytesWritten, long long int totalBytesWritten, long long int totalBytesExpectedToWrite) {
      float progress = (float) totalBytesWritten / (float) totalBytesExpectedToWrite;
      // Update progress on UI.
  }];

  // Begin uploading the file.
  [client enqueueHTTPRequestOperation:requestOperation];
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[A Review of Android remote image loading libraries]]></title><link>https://pulkitgoyal.in/review-android-remote-image-loading-libraries</link><guid isPermaLink="false">https://pulkitgoyal.in/review-android-remote-image-loading-libraries</guid><pubDate>Tue, 09 Jul 2013 21:16:27 GMT</pubDate><content:encoded>&lt;p&gt;Loading remote images from an url into &lt;code class=&quot;language-text&quot;&gt;ImageView&lt;/code&gt;s  in Android is one of the features that I have used quite extensively for almost all the Android apps that I have worked on. This isn’t really trivial as loading remote images requires creating an asynchronous task to download the image from url and then load it into the image view. There are several things that need to be taken care of when working with remote images because you can never know how large the image will be and loading a very big image into memory will cause the application to run out of memory very quicky.&lt;/p&gt;
&lt;p&gt;While working on a project that relied heavily on external images, I tried out several of available libraries (&lt;a href=&quot;https://github.com/koush/UrlImageViewHelper&quot;&gt;UrlImageViewHelper&lt;/a&gt;, &lt;a href=&quot;https://github.com/nostra13/Android-Universal-Image-Loader&quot;&gt;UniversalImageLoader&lt;/a&gt; and &lt;a href=&quot;https://square.github.io/picasso/&quot;&gt;Picasso&lt;/a&gt;) to come up with the one that performs the best.&lt;/p&gt;
&lt;p&gt;UrlImageViewLoader is a really light weight library and it works out of the box. All you need is to import the project into Eclipse, link it as a library project and start loading images into ImageViews with &lt;code class=&quot;language-text&quot;&gt;UrlImageViewHelper.setUrlDrawable(imageView, &amp;quot;https://example.com/image.png&amp;quot;);&lt;/code&gt;. It performs callback methods, caching and works with ListAdapters. But this is where the fun stops. There are not a lot of configuration options but is really easy to quickly get started with.&lt;/p&gt;
&lt;p&gt;Picasso is equally simple to use and performs advanced features like image cropping, resizing and transformations. It makes it very easy to resize the images if you already know the size of the image view you are loading the images into and the performance starts showing when you use resizing while loading a lot of images in a list view. This was something that I was using and Picasso immediately had an edge over UrlImageViewLoader for my requirements. The fact that it was developed by Jake Wharton (the developer of ActionBarSherlock) made it that much more appealing. But there were a lot of quirks and resizing didn’t seem to work always. It is still in very active development with a few commits at least every few days, but I would still wait for it to be more stable before trying it out again.&lt;/p&gt;
&lt;p&gt;The final library in my review is UniversalImageLoader which is available as a jar file that can just be dropped into the project libraries. It is considerably heavy as compared with the other two libraries in the review, but has a lot of configuration options that allow controlling just about anything with the remote image loading. One of the most important things about it is the integrated resizing of images based on a maximum size (maybe not as efficient as Picasso, but definitely stable). The library has several caching strategies for the images as well as several display options. However, it does require a bit more configuration on the part of the developer. Here are the configuration options that I ended up using with UniversalImageLoader in my Application class.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Create global configuration and initialize ImageLoader&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;DisplayImageOptions&lt;/span&gt; defaultOptions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DisplayImageOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cacheInMemory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cacheOnDisc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bitmapConfig&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Bitmap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Config&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;RGB_565&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;imageScaleType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ImageScaleType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;EXACTLY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;showStubImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image_placeholder&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;showImageForEmptyUri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drawable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image_placeholder&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;ImageLoaderConfiguration&lt;/span&gt; config &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ImageLoaderConfiguration&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getApplicationContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;defaultDisplayImageOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;defaultOptions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;ImageLoader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;config&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Useful iOS resources]]></title><link>https://pulkitgoyal.in/ios-resources</link><guid isPermaLink="false">https://pulkitgoyal.in/ios-resources</guid><pubDate>Sun, 05 May 2013 16:41:43 GMT</pubDate><content:encoded>&lt;p&gt;Its been quite some time since I began native iOS development and here&apos;s a post with my advice about some of the most useful resources for iOS developers. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://cocoapods.org/&quot;&gt;CocoaPods&lt;/a&gt;&lt;/strong&gt;: The first on my list is a wonderful dependency management library for Objective-C Projects (like &lt;a href=&quot;https://maven.apache.org/&quot;&gt;Apache Maven&lt;/a&gt; if you are coming from the Java world). With CocoaPods setup for the project, all you need to do to use other libraries is to write them in the [cci]Podfile[/cci] and do [cci]pod install[/cci]. All you need to do now is include the files and write code. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/robbiehanson/CocoaLumberjack&quot;&gt;CocoaLumberjack&lt;/a&gt;&lt;/strong&gt;: CoocaLumberjack is logging system for iOS apps. I have found it to be one of the most useful frameworks out there, its fast, its easy to configure and its been actively developed. Bonus points for integrating it with &lt;a href=&quot;https://github.com/robbiehanson/XcodeColors&quot;&gt;XCodeColors&lt;/a&gt; to see coloured logs in your console. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/AFNetworking/AFNetworking&quot;&gt;AFNetworking&lt;/a&gt;&lt;/strong&gt;: This is the one library that you will see in all such posts talking about resources for iOS developers. Why? Well, its really well designed, maintained and has a huge community of developers who have been using and contributing to it. If you want to handle network requests in your apps, you will not regret using this. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://restkit.org/&quot;&gt;RestKit&lt;/a&gt;&lt;/strong&gt;: This makes interacting with Rest services really easy and has a powerful object mapping system. RestKit&apos;s primary goal is to allow the developer to think more in terms of their application&apos;s data model and worry less about the details of sending requests, parsing responses, and building representations of remote resources.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/jdg/MBProgressHUD&quot;&gt;MBProgressHUD&lt;/a&gt;&lt;/strong&gt;: Again, one of the must use libraries. Provides beautiful HUDs and is really simple to integrate in the app. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://subtlepatterns.com/&quot;&gt;Subtle Patterns&lt;/a&gt;&lt;/strong&gt;: Subtle Patterns is a high quality (free) resource for tilable texture patterns. These patterns look really great on the iPhone and most of the patterns are usually optimized for retina display as well.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/rs/SDWebImage&quot;&gt;SDWebImage&lt;/a&gt;&lt;/strong&gt;: Provides [cci]UIImageView[/cci] category for easily loading remote images from url. Really useful if you want to network images in your app.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/michaeltyson/TPKeyboardAvoiding&quot;&gt;TPKeyboardAvoiding&lt;/a&gt;&lt;/strong&gt;: Provides UIViewController subclass that makes it easy to scroll your views to prevent them being hidden by the on screen keyboard. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://github.com/BradLarson/GPUImage&quot;&gt;GPUImage&lt;/a&gt;&lt;/strong&gt;: This is more of a domain specific library, but is a must use if you find yourself trying to play with images, live camera feed or videos. It uses GPU where possible to perform image processing operations and makes it really easy to write custom OpenGL ES filters. &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://testflightapp.com/&quot;&gt;TestFlight&lt;/a&gt; and &lt;a href=&quot;https://www.diawi.com//&quot;&gt;Diawi&lt;/a&gt;&lt;/strong&gt;: These are two services that are very useful when you want to have beta testers for your app or want to let others on the team give a packaged version of the app that they can run on their devices. I usually prefer Diawi (for no specific reason though).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://www.cocoacontrols.com/&quot;&gt;Cocoa Controls&lt;/a&gt;&lt;/strong&gt;: A great resource to explore and search custom UI controls for iOS and Mac. I always search for available controls here before trying to make one. More often than not, I find something open sourced that I can just use/extend as per my needs. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Discussion on &lt;a href=&quot;https://www.reddit.com/r/iOSProgramming/comments/1ds942/most_useful_ios_resources_for_developers/&quot;&gt;Reddit&lt;/a&gt; and &lt;a href=&quot;https://news.ycombinator.com/item?id=5661915&quot;&gt;Hacker News&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Creating video thumbnails using the iOS SDK]]></title><link>https://pulkitgoyal.in/creating-video-thumbnails-using-the-ios-sdk</link><guid isPermaLink="false">https://pulkitgoyal.in/creating-video-thumbnails-using-the-ios-sdk</guid><pubDate>Fri, 12 Apr 2013 21:58:19 GMT</pubDate><content:encoded>&lt;p&gt;For a project that I have been working on recently, I came across the need for creating thumbnail images for videos in iOS application. The iOS SDK makes it really simple to create the thumbnail images through the &lt;a href=&quot;https://developer.apple.com/library/mac/#documentation/AVFoundation/Reference/AVAssetImageGenerator_Class/Reference/Reference.html&quot;&gt;AVAssetImageGenerator&lt;/a&gt;. &lt;code class=&quot;language-text&quot;&gt;AVAssetImageGenerator&lt;/code&gt; uses the default enabled video track(s) to generate images. &lt;/p&gt;
&lt;p&gt;Generating a single image in isolation can require the decoding of a large number of video frames with complex interdependencies. If you require a series of images, you can achieve far greater efficiency using the asynchronous method, &lt;code class=&quot;language-text&quot;&gt;copyCGImageAtTime:actualTime:error:&lt;/code&gt;, which employs decoding efficiencies similar to those used during playback.&lt;/p&gt;
&lt;p&gt;We will use &lt;code class=&quot;language-text&quot;&gt;generateCGImagesAsynchronouslyForTimes:completionHandler:&lt;/code&gt;to generate the images from video. It expects an &lt;code class=&quot;language-text&quot;&gt;NSArray&lt;/code&gt; of &lt;code class=&quot;language-text&quot;&gt;NSValue&lt;/code&gt; objects, each containing a &lt;code class=&quot;language-text&quot;&gt;CMTime&lt;/code&gt;, specifying the asset times at which we need an image.&lt;/p&gt;
&lt;p&gt;Here’s a simple function that can be used to generate images asynchronously from the video:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;-(void)generateImage
{
    NSURL *url = [NSURL fileURLWithPath:_videoPath];
    AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:url options:nil];
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    generator.appliesPreferredTrackTransform=TRUE;

    CMTime thumbTime = CMTimeMakeWithSeconds(30,30);
    
    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
        if (result != AVAssetImageGeneratorSucceeded) {
            NSLog(@&amp;quot;couldn&amp;#39;t generate thumbnail, error:%@&amp;quot;, error);
        }
        // TODO Do something with the image
    };
    
    CGSize maxSize = CGSizeMake(128, 128);
    generator.maximumSize = maxSize;
    [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];
    
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Facebook Android SDK reauthorizeForPublish() loses old permissions]]></title><link>https://pulkitgoyal.in/facebook-android-sdk-reauthorizeforpublish-loses-old-permissions</link><guid isPermaLink="false">https://pulkitgoyal.in/facebook-android-sdk-reauthorizeforpublish-loses-old-permissions</guid><pubDate>Mon, 14 Jan 2013 20:32:00 GMT</pubDate><content:encoded>&lt;p&gt;In &lt;a href=&quot;https://pulkitgoyal.in/2013/01/09/requesting-extended-permissions-facebook-sdk-android/&quot; title=&quot;Requesting extended permissions | Facebook SDK | Android&quot;&gt;Requesting extended permissions&lt;/a&gt;, I explained how to request extended permissions with the Facebook Android SDK. If you use this method to request different kinds of permissions at different stages, you would notice that making a call to [cci]session.reauthorizeForPublish()[/cci] with new permissions clears the already existing permissions from the session object and thus the call [cci]session.getPermissions()[/cci] would later return just the new permissions that are recently granted. This means that the Session object’s notion of its permissions is out of sync with the Facebook service and the access token associated with the Session still has those permissions and can still be used to make Graph API calls requiring any of the permissions it has been granted earlier (unless the user has subsequently revoked any of them, of course). This is a &lt;a href=&quot;https://stackoverflow.com/a/13655004/643109&quot;&gt;bug with the Facebook SDK&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An approach to work around this problem is to store the permissions that have been granted to us by persisting it in the &lt;a href=&quot;https://developer.android.com/reference/android/app/Application.html&quot;&gt;Android Application class&lt;/a&gt;. The application class is the base class to maintain global application state. If you don’t already have an application class for your application, you can create one by extending &lt;code class=&quot;language-text&quot;&gt;Application&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyApplication&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Application&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

	&lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Collection&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; sessionPermissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;permissions &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			permissions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		permissions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sessionPermissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permissions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;addPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Collection&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; newPermissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permissions &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permissions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;HashSet&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permissions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newPermissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clearPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permissions &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permissions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Register the class in &lt;code class=&quot;language-text&quot;&gt;AndroidMaifest&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;application&lt;/span&gt;
 &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;icon&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@drawable/icon&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
 &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@string/app_name&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
 &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;MyApplication&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The first thing we need to do now is to obtain the current permissions granted by the user for our session when the app is launched  (and user is already loggeed in) or when the user logs in using Facebook. I use the following method to retrieve current permissions from Facebook and persist them in the application object. This should be called in &lt;code class=&quot;language-text&quot;&gt;onSessionStateChanged&lt;/code&gt; when a new session is opened or in &lt;code class=&quot;language-text&quot;&gt;onCreate&lt;/code&gt; if the user is already logged in.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;retreiveCurrentPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;FacebookClient&lt;/span&gt; fbClient &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;DefaultFacebookClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAccessToken&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;JsonObject&lt;/span&gt; resultJson &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; fbClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetchObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;me/permissions&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;JsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;ArrayList&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;resultJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token class-name&quot;&gt;JsonObject&lt;/span&gt; permissionsJson &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; resultJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;data&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; key &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;JsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getNames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;permissionsJson&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;permissionsJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
					permissions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MyApplication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getApplication&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;permissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;JsonException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;printStackTrace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Another important point to keep in mind is to clear the permissions if the user logs out of Facebook. This can be done by calling &lt;code class=&quot;language-text&quot;&gt;((MyApplication) getApplication()).clearPermissions();&lt;/code&gt; in &lt;code class=&quot;language-text&quot;&gt;onSessionStateChanged&lt;/code&gt; when the session is closed.&lt;/p&gt;
&lt;p&gt;Now we are persisting the session permissions in our application object. Before performing an operation that requires extended permission, we should now check if the required permissions are already present in &lt;code class=&quot;language-text&quot;&gt;((MyApplication)getApplication()).getPermissions(session.getPermissions());&lt;/code&gt; and make a Reauthorization request if this is not the case. In this case, we will then have to add the permissions in &lt;code class=&quot;language-text&quot;&gt;onSessionStateChanged&lt;/code&gt; if the state of the session is &lt;code class=&quot;language-text&quot;&gt;SessionState.OPENED_TOKEN_UPDATED&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Requesting extended permissions | Facebook SDK | Android]]></title><link>https://pulkitgoyal.in/requesting-extended-permissions-facebook-sdk-android</link><guid isPermaLink="false">https://pulkitgoyal.in/requesting-extended-permissions-facebook-sdk-android</guid><pubDate>Wed, 09 Jan 2013 18:13:24 GMT</pubDate><content:encoded>&lt;p&gt;Facebook documentation focuses on the point that applications accessing user’s data from Facebook should not ask for any permission they are not going to make use of (especially &lt;code class=&quot;language-text&quot;&gt;publish_stream&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;offline_access&lt;/code&gt;). Here’s a quote from a Facebook document:&lt;/p&gt;
&lt;blockquote&gt;
Depending on your application’s needs, you may need additional permissions from the user. A large number of calls do not require any additional permissions, so you should first make sure you need a permission. This is a good idea because this step potentially adds friction to the user’s process. Another point to remember is that this call can be made even after the user has first connected. So you may want to delay asking for permissions until as late as possible.
&lt;/blockquote&gt;
&lt;p&gt;However, while working on an Android application that uses the Facebook SDK, I couldn’t find good documentation on how to do this. Here’s what I have been able to come up with by reading the code in sample Facebook applications in the SDK. &lt;/p&gt;
&lt;p&gt;Let us first define what permissions we are going to need. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// List of additional write permissions being requested&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; PERMISSIONS &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Arrays&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;asList&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;publish_stream, publish_actions&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Request code for reauthorization requests. &lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; REAUTH_ACTIVITY_CODE &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 

&lt;span class=&quot;token comment&quot;&gt;// Flag to represent if we are waiting for extended permissions&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;boolean&lt;/span&gt; pendingAnnounce &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As you might have guessed from the permissions, we would be publishing some thing to user’s wall. Lets call this method that handles the sesison as &lt;code class=&quot;language-text&quot;&gt;publishAnnounce&lt;/code&gt;. We add our activity as the session callback for Facebook session updates. You can pass objects of any class that implements &lt;code class=&quot;language-text&quot;&gt;StatusCallback&lt;/code&gt;. We will see more about this later. Here’s what &lt;code class=&quot;language-text&quot;&gt;publishAnnounce&lt;/code&gt; would look like. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;handleAnnounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	pendingAnnounce &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getActiveSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isOpened&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;permissions&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;containsAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;PERMISSIONS&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		pendingAnnounce &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Mark that we are currently waiting for confirmation of publish permissions &lt;/span&gt;
		session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addCallback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
		&lt;span class=&quot;token function&quot;&gt;requestPublishPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; PERMISSIONS&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; REAUTH_ACTIVITY_CODE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// TODO: Publish the post. You would need to implement this method to actually post something&lt;/span&gt;
	&lt;span class=&quot;token function&quot;&gt;publishMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;requestPublishPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Activity&lt;/span&gt; activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ReauthorizeRequest&lt;/span&gt; reauthRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ReauthorizeRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setRequestCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reauthorizeForPublish&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reauthRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We first checked if we had all the required permissions. If not, we create a new ReauthorizeRequest with the set of permissions that we are requesting. This guides user outside our app to either the Facebook app or browser to confirm the permissions. When the user confirms the requests, he is redirected back to our application and &lt;code class=&quot;language-text&quot;&gt;onActivityResult&lt;/code&gt; for the Activity that invoked the reauthorization request is called. Let us see how it would look like: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onActivityResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; requestCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; resultCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onActivityResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requestCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resultCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;case&lt;/span&gt; REAUTH_ACTIVITY_CODE&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getActiveSession&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;onActivityResult&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; requestCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resultCode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;All we need to do here is to pass the result to the active Facebook session. This processes the result and calls the &lt;code class=&quot;language-text&quot;&gt;onSessionStateChanged&lt;/code&gt; if the session state changes.  We then check in that method if our token was successfully updated and try to publish the message again.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onSessionStateChange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SessionState&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Exception&lt;/span&gt; exception&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;isOpened&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;SessionState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;OPENED_TOKEN_UPDATED&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token comment&quot;&gt;// Session updated with new permissions&lt;/span&gt;
			&lt;span class=&quot;token comment&quot;&gt;// so try publishing once more.&lt;/span&gt;
			&lt;span class=&quot;token function&quot;&gt;tokenUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * Called when additional permission request is copmleted successfuly.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;tokenUpdated&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// Check if a publish action is in progress&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// awaiting a successful reauthorization&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pendingAnnounce&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// Publish the action&lt;/span&gt;
		&lt;span class=&quot;token function&quot;&gt;handleAnnounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;EDIT:&lt;/strong&gt;
For the new SDK(3.0.1), I have the following:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;requestPublishPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Activity&lt;/span&gt; activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewPermissionsRequest&lt;/span&gt; reauthRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewPermissionsRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setRequestCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;requestNewPublishPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reauthRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;requestReadPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Activity&lt;/span&gt; activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt; session&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;session &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewPermissionsRequest&lt;/span&gt; reauthRequest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Session&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;NewPermissionsRequest&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; permissions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setRequestCode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;requestCode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		session&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;requestNewReadPermissions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reauthRequest&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Extending RestFB model with extra fields]]></title><link>https://pulkitgoyal.in/extending-restfb-model-with-extra-fields</link><guid isPermaLink="false">https://pulkitgoyal.in/extending-restfb-model-with-extra-fields</guid><pubDate>Thu, 03 Jan 2013 17:42:30 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://restfb.com/&quot;&gt;RestFB &lt;/a&gt;is a simple and flexible Facebook Graph API client for Java. I have used it recently for one of my projects and it greatly simplifies the graph requests. However, as the Graph API is constantly changing, it is really hard for the developers to keep updated with the latest additions in the graph api. I found that the Post model in RestFB representing the news feed posts didn’t have any story field to represent the story being posted on Facebook. RestFB makes it really simple to extend the existing models with extra information without having to change anything in the library code. To add the story field, I created a custom class &lt;code class=&quot;language-text&quot;&gt;PostWithStory&lt;/code&gt; containing the field. All we need to have the field is to create a new data member and annotate it with &lt;code class=&quot;language-text&quot;&gt;@Facebook&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;com&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;restfb&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Facebook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token namespace&quot;&gt;com&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;restfb&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;types&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Post&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PostWithStory&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token annotation punctuation&quot;&gt;@Facebook&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;story&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; story&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getStory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; story&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setStory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; story&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;story &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; story&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, when retrieving the posts from news feed, I use the following to get my posts with the story field.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;Connection&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;PostWithStory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; myFeed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; facebookClient&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fetchConnection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;me/home&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;PostWithStory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to have more control on the data that is being returned, you can have a method in the custom class annotated with &lt;code class=&quot;language-text&quot;&gt;@JsonMappingCopmleted&lt;/code&gt; and it will be called after RestFB finishes mapping the Jsonobject.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// You can annotate methods with @JsonMappingCompleted to perform&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// post-mapping operations.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// This is useful if you want to massage the data FB returns.&lt;/span&gt;

&lt;span class=&quot;token annotation punctuation&quot;&gt;@JsonMappingCompleted&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;allDone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;JsonMapper&lt;/span&gt; jsonMapper&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lotsOfNumbers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;I was expecting more numbers!&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Rendering photos and videos from Facebook news feed in Android application]]></title><link>https://pulkitgoyal.in/rendering-photos-and-videos-from-facebook-news-feed-in-android-application</link><guid isPermaLink="false">https://pulkitgoyal.in/rendering-photos-and-videos-from-facebook-news-feed-in-android-application</guid><pubDate>Thu, 03 Jan 2013 09:24:16 GMT</pubDate><content:encoded>&lt;p&gt;In the &lt;a href=&quot;https://pulkitgoyal.in/2012/12/26/getting-all-photos-and-videos-from-facebook-news-feed/&quot;&gt;last post&lt;/a&gt;, I described how to get photos and videos from a user’s Facebook news feed. In this post, I will continue on and describe how to build a simple user interface for showing these photos and videos for an Android app. Let’s have a look at how this is going to look like:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1392235473/Screen-Shot-2013-01-01-at-7_21_20-PM_tsfgbr.png&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_552,w_438/v1392235473/Screen-Shot-2013-01-01-at-7_21_20-PM_tsfgbr.png&quot; alt title=&quot;Screen Shot 2013-01-01 at 7.21.20 PM&quot; width=&quot;238&quot; height=&quot;300&quot; class=&quot;aligncenter size-medium wp-image-717&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let us first build a model that would describe the main parts of data that we obtained from the fql queries. We will extract the main parts in the media objects as follows:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;has&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;has&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;media&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token comment&quot;&gt;// Get attachment name and href&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; attachmentName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStringFromJsonIfExists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
			&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; attachmentHref &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStringFromJsonIfExists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
			mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Get id of actor who posted the content&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; actorId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;actor_id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; postId &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;post_id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; createdTime &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;created_time&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token class-name&quot;&gt;JsonArray&lt;/span&gt; mediaArray &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonArray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;media&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; mediaArray&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;JsonObject&lt;/span&gt; mediaObject &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaArray&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; type &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// Get thumbnail url&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; thumbnailUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStringFromJsonIfExists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaObject&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token class-name&quot;&gt;MediaPost&lt;/span&gt; post &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MediaPost&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;attachmentName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attachmentHref&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; actorId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; postId&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; createdTime&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
				thumbnailUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; fbid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; mediaObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;has&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Photo&lt;/span&gt;
			fbid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fbid&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;has&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fb_object_id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			fbid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; mediaResultObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;fb_object_id&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setFbId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;fbid&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setMediaObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaObject&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAlt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mediaObject&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;alt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		posts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The mediaObject here is a jsonObject parsed from a json object like so:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;actor_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;202209223157016&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;created_time&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1357059211&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;likes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://www.facebook.com/browse/likes/?id=501300199914582&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;count&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;sample&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;100001172558908&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;202209223157016&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;100002876441601&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;friends&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;100000185344749&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;user_likes&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;can_like&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;post_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;202209223157016_501300213247914&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&quot;attachment&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;media&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;href&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://www.facebook.com/photo.php?fbid=501300199914582&amp;amp;set=a.202685659776039.53449.202209223157016&amp;amp;type=1&amp;amp;relevant_count=1&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;alt&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;I am alone but not dead ... rnrnrn~ Alone Tree Silhouette at Railay Beach&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;src&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://fbcdn-photos-a.akamaihd.net/hphotos-ak-prn1/12594_501300199914582_1535726991_s.jpg&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token property&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;aid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;202209223157016_53449&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;pid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;202209223157016_1613061&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;fbid&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;501300199914582&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;owner&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;202209223157016&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;index&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;width&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;634&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;token property&quot;&gt;&quot;height&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;caption&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;properties&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;icon&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://fbstatic-a.akamaihd.net/rsrc.php/v2/yz/r/StEh3RhPvjk.gif&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;fb_object_type&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&quot;fb_object_id&quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;202209223157016_1613061&quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s the layout we will use for each object:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;RelativeLayout&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;android&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;https://schemas.android.com/apk/res/android&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;fill_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;background&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@drawable/gradient_background_gray&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;paddingLeft&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;5dp&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;paddingRight&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;5dp&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ImageView&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/imageView&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;match_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;match_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_alignParentLeft&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_centerVertical&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@drawable/abs__ab_bottom_solid_dark_holo&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ImageView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;LinearLayout&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/linearLayout1&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;match_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_alignParentLeft&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_alignParentTop&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;background&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@color/TranslucentBlack&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;orientation&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;vertical&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;TextView&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/attachment_name&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_gravity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;center_horizontal&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;gravity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;center_horizontal&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;text&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Medium Text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textAppearance&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?android:attr/textAppearanceMedium&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textColor&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@color/facebookName&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textStyle&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;bold&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;LinearLayout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;LinearLayout&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;match_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_alignParentBottom&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_alignParentLeft&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;background&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@color/TranslucentBlack&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;orientation&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;vertical&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;TextView&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/picture_title&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_gravity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;center_horizontal&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;ellipsize&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;end&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;gravity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;center_horizontal&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;maxLines&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;3&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;text&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Medium Text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textAppearance&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?android:attr/textAppearanceMedium&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textColor&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@color/WhiteSmoke&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;

        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;TextView&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/user_name&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;text&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;Medium Text&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textColor&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@color/facebookName&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_gravity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;right&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
            &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;textAppearance&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;?android:attr/textAppearanceSmall&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;LinearLayout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ImageButton&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/playButton&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;wrap_content&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_centerHorizontal&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_centerVertical&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@drawable/ic_play&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;RelativeLayout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We will use a custom PagerAadpter to render each item in the page. Here’s the function that would then instantiate each view in the PagerAdapter.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Object&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;instantiateItem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; collection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; position&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;LayoutInflater&lt;/span&gt; inflater &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;LayoutInflater&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; collection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSystemService&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
			&lt;span class=&quot;token class-name&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;LAYOUT_INFLATER_SERVICE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; view &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; inflater&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;inflate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;layout&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;view_image_photo&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MediaPost&lt;/span&gt; post &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; posts&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; thumbnailUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getThumbnailUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;video&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// Overlay play button and handle click.&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;ImageButton&lt;/span&gt; imageButton &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ImageButton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;playButton&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		imageButton&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setOnClickListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OnClickListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;token function&quot;&gt;playVideo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMediaObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getJsonObject&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;video&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;photo&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// Hide play button&lt;/span&gt;
		view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;playButton&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setVisibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GONE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// Get better thumbnail url.&lt;/span&gt;
		thumbnailUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;https://graph.facebook.com/&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFbId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/picture?type=normal&amp;amp;access_token=&quot;&lt;/span&gt;
				&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; accessToken&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Load thumbnail image in image view&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thumbnailUrl &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;ImageView&lt;/span&gt; imageView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ImageView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;imageView&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		imageLoader&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;DisplayImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;thumbnailUrl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; imageView&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Add details above and below&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;TextView&lt;/span&gt; mediaName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;picture_title&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;TextView&lt;/span&gt; attachmentNameTextView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;attachment_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;TextView&lt;/span&gt; userNameTextView &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;TextView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;findViewById&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;R&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user_name&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token comment&quot;&gt;// Set user name or hide view.&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getActorId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		userNameTextView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;users&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getActorId&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		userNameTextView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setVisibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GONE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	mediaName&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAlt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttachmentName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttachmentName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		attachmentNameTextView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttachmentName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttachmentHref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; attachmentNameTextView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getParent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setOnClickListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;OnClickListener&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;token annotation punctuation&quot;&gt;@Override&lt;/span&gt;
				&lt;span class=&quot;token keyword&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt; browserIntent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ACTION_VIEW&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttachmentHref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
					context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startActivity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;browserIntent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		attachmentNameTextView&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setVisibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;View&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;GONE&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

	&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ViewPager&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; collection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;addView&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;view&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; view&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Playing the video from the url on Android can be a bit tricky. One thing that I found about streaming videos on Android is that it is difficult to stream videos with url beginning with https. Fortunately, for the videos that we receive from facebook, just converting the urls to http works fine. Here’s how you would play the video in the default media player in android.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;playVideo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;JsonObject&lt;/span&gt; video&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; videoUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStringFromJsonIfExists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;video&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;source_url&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;videoUrl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;https&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			videoUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;http&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; videoUrl&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// First try to obtain correct mime type and play video.&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt; intent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ACTION_VIEW&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; extension &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; android&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;webkit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MimeTypeMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFileExtensionFromUrl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;videoUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;String&lt;/span&gt; mimetype &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; android&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;webkit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;MimeTypeMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getSingleton&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMimeTypeFromExtension&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;extension&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		intent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setDataAndType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;videoUrl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mimetype&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startActivity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;intent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;ActivityNotFoundException&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// Unable to play using mime type.&lt;/span&gt;
		&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt; intent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Intent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ACTION_VIEW&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		intent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Uri&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getStringFromJsonIfExists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;video&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;display_url&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startActivity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;intent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We are almost done. Now we just need to create a ViewPager and set the adapter. Create the view pager in the layout and then get the reference to the ViewPager in your Activity/Fragment and set the subclass of PagerAdapter you just created.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;android.support.v4.view.ViewPager&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;@+id/viewPager&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;match_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;android:&lt;/span&gt;layout_height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;match_parent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Getting all photos and videos from Facebook news feed]]></title><link>https://pulkitgoyal.in/getting-all-photos-and-videos-from-facebook-news-feed</link><guid isPermaLink="false">https://pulkitgoyal.in/getting-all-photos-and-videos-from-facebook-news-feed</guid><pubDate>Wed, 26 Dec 2012 11:34:11 GMT</pubDate><content:encoded>&lt;p&gt;I have been working with the Facebook API recently and I came across the need to get all the photos and videos in the news feed. Given the comprehensive Graph API, I had initially thought that it would be straight forward getting these details from the news feed. After struggling a bit with the available API methods, I decided that FQL might be the best way to go about this. And it turned out that doing this with FQL wasn’t all that difficult. Here’s a simple FQL query for getting all the photos and videos in the news feed. &lt;code class=&quot;language-text&quot;&gt;stream_filter&lt;/code&gt; contains the filters for filtering the stream of posts. This contains several filters that include the lists that the user has built and some default filters like the ones for photos and videos.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sql&quot;&gt;&lt;pre class=&quot;language-sql&quot;&gt;&lt;code class=&quot;language-sql&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; actor_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; created_time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; likes&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; post_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; attachment
&lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; stream
&lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; filter_key &lt;span class=&quot;token operator&quot;&gt;IN&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;SELECT&lt;/span&gt; filter_key &lt;span class=&quot;token keyword&quot;&gt;FROM&lt;/span&gt; stream_filter &lt;span class=&quot;token keyword&quot;&gt;WHERE&lt;/span&gt; uid &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; me&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;AND&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Photos&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;OR&lt;/span&gt; name &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;Video&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can have a look at the results of the query using the &lt;a href=&quot;https://developers.facebook.com/tools/explorer/&quot;&gt;Graph API Explorer&lt;/a&gt;. This gives us the actor_id which is the id of the user/page on Facebook that has shared the post, the likes on the post, the id for the post and an attachment that contains more details about the media objects included in the posts. In order to get the details for the users who have shared the posts, we need to use multiple fql queries to query the profile table for user details.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	media&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SELECT actor_id, created_time, likes, post_id, attachment FROM stream WHERE filter_key IN ( SELECT filter_key FROM stream_filter WHERE uid = me() AND (name = &quot;Photos&quot; OR name = &quot;Video&quot;))&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
	users&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;SELECT id, name, url, pic FROM profile WHERE id IN (SELECT actor_id FROM #media)&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I will describe in the next post how we can parse the results from these queries to build a simple screen in Android with the results that allow users to browse through these photos and videos.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Building an extensible news feed reader]]></title><link>https://pulkitgoyal.in/building-an-extensible-news-feed-reader</link><guid isPermaLink="false">https://pulkitgoyal.in/building-an-extensible-news-feed-reader</guid><pubDate>Fri, 23 Nov 2012 17:46:55 GMT</pubDate><content:encoded>&lt;p&gt;We built a news reader client for Android using Titanium called hackurls which shows the top news from some of the best technology news sharing websites. How long it took us? Less than a day. Although, I wouldn’t call the UI for the client to be very good, I find the app in itself to be very useful. Building this was fun and it wasn’t overly complicated. We built simple parsers for the feeds to get them to a common format so that our rendering could be done easily. This also leaves us a lot of space to improve the user experience while keeping most of our code for the backend un touched. Here’s an example for the service that retrieves news from Hackernews.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;HackerNews&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_HN_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://hndroidapi.appspot.com/news/format/json/page/?appid=YOUR_APP_ID&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_HN_BASE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://news.ycombinator.com/&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;/**
     * Gets the domain of a url
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDomain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; match &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;/:\/\/(.[^/]+)/&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;match &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;match&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;www.&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;


    &lt;span class=&quot;token comment&quot;&gt;/**
     * Gets the post from Hackernews.
     */&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;getPosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xhr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Titanium&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Network&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createHTTPClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        xhr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;responseText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; parsedJson &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;responseText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parsedJson &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; post &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; domain &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDomain&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                    items&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
                        title &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        url &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;domain &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_HN_BASE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        id &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;item_id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        commentCount &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;comments&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        time &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        timetype &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;pretty&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        details &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; domain&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        user &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;user&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        points &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;score&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
                        description &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; post&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;description
                    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;token function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token comment&quot;&gt;// open the client&lt;/span&gt;
        xhr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_HN_URL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;token comment&quot;&gt;// send the data&lt;/span&gt;
        xhr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; HackerNews&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here’s another module that parses data for posts from Reddit and Proggit.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_REDDIT_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.reddit.com/hot.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_PROGGIT_URL&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.reddit.com/r/programming/hot.json&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Reddit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;url&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; type&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_REDDITBASE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;https://www.reddit.com&apos;&lt;/span&gt;
	&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;getPosts&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
		&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xhr &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Titanium&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Network&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createHTTPClient&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		xhr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onload&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; parsedJson &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;responseText&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;parsedJson &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
				&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; items &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; j&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
					&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; postData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; parsedJson&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
					items&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
						title &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						url &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STR_REDDITBASE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;permalink&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						id &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						commentCount &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;num_comments&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						points &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;score&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						time &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;created_utc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						timetype &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;timestamp&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						user &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;author&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						thumbnail &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;thumbnail&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
						details &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;type&lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;proggit&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;domain&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;postData&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;subreddit
					&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;API&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
				&lt;span class=&quot;token function&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; items&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
			&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
		&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;token comment&quot;&gt;// open the client&lt;/span&gt;
		xhr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;GET&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; url&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

		&lt;span class=&quot;token comment&quot;&gt;// send the data&lt;/span&gt;
		xhr&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

	&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Reddit&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Once we have all the posts with the details that we have here, building an amazing UI is the only thing that remains which I will leave up to you. There are similar parsers that we made for Slashdot, Techmeme, Wired and Dzone. If you want to give this a try, feel free to fork &lt;a href=&quot;https://github.com/sapandiwakar/hackurls&quot; target=&quot;_blank&quot;&gt;Hackurls&lt;/a&gt; on github or get &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.hackurls&amp;hl=en&quot; target=&quot;_blank&quot;&gt;Hackurls on Play store&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Managing multiple languages with Appcelerator Titanium]]></title><link>https://pulkitgoyal.in/managing-multiple-languages-with-appcelerator-titanium</link><guid isPermaLink="false">https://pulkitgoyal.in/managing-multiple-languages-with-appcelerator-titanium</guid><pubDate>Sat, 17 Nov 2012 14:44:26 GMT</pubDate><content:encoded>&lt;p&gt;Titanium provides a number of JavaScript functions in the &lt;code class=&quot;language-text&quot;&gt;Titanium.Locale&lt;/code&gt; namespace for use in localization. It also provides String formatting functions to handle dates, times, currencies, and more. You can even internationalize the name of your app itself. There’s a good tutorial on how to do this &lt;a href=&quot;https://wiki.appcelerator.org/display/guides/Internationalization&quot;&gt;here&lt;/a&gt;. Titanium also allows you to define internationalization files and automatically chooses the correct one based on device locale settings. But what if you want to allow the user to choose the language for the app from within the application settings? To provide this functionality in an app built with Titanium, we would need to override the function &lt;code class=&quot;language-text&quot;&gt;L()&lt;/code&gt; that Titanium uses to retrieve localised strings from one of the xml files. Here, we will parse the xml files manually based on the user’s selected language and find the localised string that user is looking for.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * Returns the text based on the selected language in the application settings.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;L&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageXML &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageXML &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; langFile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Properties&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;SETTING_LANGUAGE&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// We should store user&apos;s language setting in SETTING_LANGUAGE&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filesystem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filesystem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resourcesDirectory&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;i18n/&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; langFile &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.xml&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Get the corresponding file from i18n&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; langFile &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Fall back to english as the default language&lt;/span&gt;
      file &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filesystem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getFile&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Filesystem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;resourcesDirectory&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;i18n/&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; langFile &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;.xml&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xmltext &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; file&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;read&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xmldata &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Titanium&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;XML&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseString&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xmltext&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Parse the xml&lt;/span&gt;
    Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageXML &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; xmldata&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Store the parsed xml so that we don&apos;t parse everytime L() is called&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Get the localised string from xml file&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xpath &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;/resources/string[@name=&apos;&quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; text &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;&apos;]/text()&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; 
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; result &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Ti&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;App&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;languageXML&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;evaluate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;xpath&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;result&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; result&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;text&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; text&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Return the text if localised version not found&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, all you need is to include this in every file and whenever you want to use a localised string, use &lt;code class=&quot;language-text&quot;&gt;L(&amp;#39;my-string-here&amp;#39;)&lt;/code&gt; in its place. Don’t forget to set the currently selected language using &lt;code class=&quot;language-text&quot;&gt;Ti.App.Properties.setString(&amp;#39;SETTING_LANGUAGE&amp;#39;,&amp;#39;en&amp;#39;);&lt;/code&gt; All that’s left now is to create your internationalisation files in i18n directory inside your app resources and declare strings in the following format:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token prolog&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;home&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Home&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;string&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;settings&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;Settings&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;string&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;resources&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Moving content located under the iOS keyboard]]></title><link>https://pulkitgoyal.in/moving-content-located-under-the-ios-keyboard</link><guid isPermaLink="false">https://pulkitgoyal.in/moving-content-located-under-the-ios-keyboard</guid><pubDate>Mon, 12 Nov 2012 17:23:48 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;The iOS keyboard slides from the bottom of the screen and is positioned on the top of application&apos;s content. Apple wrote a &lt;a href=&quot;https://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html&quot; target=&quot;_blank&quot;&gt;guide&lt;/a&gt; for handling such events and moving the content from behind the keyboard. The basic workflow for this is to listen to the keyboard notifications, get the size of the keyboard, adjust the bottom content inset of scroll view by the keyboard height and scroll the target text field into view.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;// Call this method somewhere in your view controller setup code.
- (void)registerForKeyboardNotifications
{
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(keyboardWasShown:)
            name:UIKeyboardDidShowNotification object:nil];

   [[NSNotificationCenter defaultCenter] addObserver:self
             selector:@selector(keyboardWillBeHidden:)
             name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.
- (void)keyboardWasShown:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it&amp;#39;s visible
    // Your application might not need or want this behavior.
    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;
    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);
        [scrollView setContentOffset:scrollPoint animated:YES];
    }
}

// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p align=&quot;justify&quot;&gt;There is one important point that Apple misses here in the guide though. &lt;strong&gt;This doesn&apos;t work very well when the app is operating in the landscape mode&lt;/strong&gt;. I struggled with this for quite some time before actually figuring out that the keyboard height is always returned for the portrait mode irrespective of the orientation that the app is currently operating in. Here&apos;s a quick hack to fix this. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;objective-c&quot;&gt;&lt;pre class=&quot;language-objective-c&quot;&gt;&lt;code class=&quot;language-objective-c&quot;&gt;if (UIInterfaceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
    kbSize = CGSizeMake(kbSize.height, kbSize.width);
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Move, Copy or swap DOM elements?]]></title><link>https://pulkitgoyal.in/645</link><guid isPermaLink="false">https://pulkitgoyal.in/645</guid><pubDate>Mon, 03 Sep 2012 14:24:50 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;If you have been reading my posts, you probably already know that I worked on jMatrixBrowse this summer. For those who don&apos;t know, it is a jQuery plugin that allows creating browsable matrices (just like Google maps) on the web. See a quick demo &lt;a href=&quot;https://pulkitgoyal.in/Demo/jMatrixBrowse/demo/basic/html/jMatrixBrowseDemo.html&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;An important objective for the plugin was not to make a lot of requests to the backend to obtain the data in the matrix. However, we still wanted to have the data available for the user as soon as he reaches a particular cell. We implemented a background caching module for this that loaded all the cells in the matrix in a separate background container so that all the data is available in the DOM when it is required. This was implemented as a completely separate module which handled all calls to the backend. So the main plugin only made requests to the background loading module and it decided which cells it already had and which it needed to retrieve from the API on the go and sent the results to the renderer. &lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;This was working great. The only thing that we needed to take care of was how to swap in the content from the background to the matrix content. Here are some experimental results from three strategies that we tested.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Strategy 1: Load the background data in a separate container and when more cells are required in the matrix, we clone and move the cells from the background container to the main matrix container at the corresponding position. &lt;/li&gt;
	&lt;li&gt;Strategy 2: Load the background data in the same container as the matrix content but make it initially hidden. Change the top/left of the background cells and show them when new data is required in the matrix. &lt;/li&gt;
	&lt;li&gt;Strategy 3: Load the background data in a separate container and when new data is required in the matrix, swap the html of the new data in place of the already existing cells. &lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;|  Reload window   | Strategy  | Average Time (in msec)|
| One Page (5x10)  |     1     |            17         |
| One Page (5x10)  |     2     |             8         |
| One Page (5x10)  |     3     |             4         |
| One Row  (1x10)  |     1     |             4         |
| One Row  (1x10)  |     2     |             1.5       |
| One Row  (1x10)  |     3     |             1         |&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p align=&quot;justify&quot;&gt;As expected the first strategy is the slowest because cloning DOM elements is slow. Strategy 2 was the next slowest because moving content in the DOM is slow as well. The fastest was swapping the HTML content which required just about 1ms for loading one row of cells which is a good response time.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;If you want to have a detailed look at how these strategies were implemented, have a look at the jMatrixBrowse code on &lt;a href=&quot;https://github.com/pulkit110/jMatrixBrowse/&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Handle keyboard shortcuts with jQuery]]></title><link>https://pulkitgoyal.in/handle-keyboard-shortcuts-with-jquery</link><guid isPermaLink="false">https://pulkitgoyal.in/handle-keyboard-shortcuts-with-jquery</guid><pubDate>Tue, 28 Aug 2012 20:55:30 GMT</pubDate><content:encoded>&lt;p&gt;When you start building an application for the web, one of the features that almost always gets overlooked is accessibility. There are lots of plugins out there and most of them just ignore this. During the summer of 2011, I worked as a Google Summer of Code student for Inclusive Design Institute and the most unique thing about them was their focus on accessibility. I developed an image editor [&lt;a href=&quot;https://github.com/pulkit110/imageEditor&quot; target=&quot;_blank&quot;&gt;source&lt;/a&gt;][&amp;#x3C;a href=&quot;https://pulkitgoyal.in/imageeditor/&quot;&gt;demo&amp;#x3C;/a&gt;] component for the web. One of my focus during  the development was to allow editing the images on the web without the use of mouse.&lt;/p&gt;
&lt;p&gt;During this summer, I worked with NESCent on the development of jMatrixBrowse[&lt;a href=&quot;https://github.com/pulkit110/jMatrixBrowse&quot; target=&quot;_blank&quot;&gt;source&lt;/a&gt;][&amp;#x3C;a href=&quot;https://pulkitgoyal.in/demo/jmatrixbrowse/&quot; target=&quot;_blank&quot;&gt;demo&amp;#x3C;/a&gt;]. This summer as well, I focused quite a lot on the keyboard accessibility for jMatrixBrowse. In this post, I’ll walk you through the process of creating keyboard shortcuts for jQuery plugins. And its really simple, thanks to &lt;a href=&quot;https://github.com/jeresig/jquery.hotkeys&quot; target=&quot;_blank&quot;&gt;jquery.hotkeys&lt;/a&gt; maintained by &lt;a href=&quot;https://github.com/jeresig&quot; target=&quot;_blank&quot;&gt;jeresig&lt;/a&gt;, the creator of jQuery.&lt;/p&gt;
&lt;p&gt;The first step is to download the plugin. Its just one file. &lt;a href=&quot;https://github.com/jeresig/jquery.hotkeys/blob/master/jquery.hotkeys.js&quot; target=&quot;_blank&quot;&gt;Get this&lt;/a&gt;. Now, its really simple to add keyboard shortcuts. Just include this script in the html. Here’s how you would now bind these in your js.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;keydown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;right&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// right arrow key pressed&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;keydown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;left&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// left arrow key pressed&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;keydown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// up arrow key pressed&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;keydown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;down&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// down arrow key pressed&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;document&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;bind&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;keydown&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;ctrl+up&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ctrl + up arrow key pressed&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just add any combination of shortcuts that you want to bind to. Keep in mind not to use common browser shortcuts  because the browsers might handle these shortcuts on their own and not pass them to your page. Firefox seems to be the most liberal in this regard and Safari the most restricting. So I would test the shortcuts in Safari to see if these are actually passed to my script.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Custom jQuery UI Draggable bounds]]></title><link>https://pulkitgoyal.in/custom-jquery-ui-draggable-bounds</link><guid isPermaLink="false">https://pulkitgoyal.in/custom-jquery-ui-draggable-bounds</guid><pubDate>Sat, 25 Aug 2012 16:36:05 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;jQuery-UI draggable is very good for creating draggable components. It was perfect for the creating jMatrixBrowse. &lt;a href=&quot;https://github.com/pulkit110/jMatrixBrowse&quot; target=&quot;_blank&quot;&gt;jMatrixBrowse&lt;/a&gt; is a jQuery plugin that allows creating large browsable matrices (like Google Maps) in the browser. jQuery UI Draggable, like the other jQuery UI widgets, is highly customisable. But I feel that the customisability is still a bit under documented. You can find a whole lot of new customisation possibilities if you dive into its code. For the project, I required a custom containment handler to be called to decide if the containment relation is satisfied or not. jQuery UI Draggable already gives a containment option but that only allows to contain the draggable element inside an already existing element or by giving absolute bounds. I wanted to check these bounds based on the current matrix state.
&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;Draggable uses the &lt;a href=&quot;https://github.com/jquery/jquery-ui/blob/master/ui/jquery.ui.draggable.js#L416&quot; target=&quot;_blank&quot;&gt;generatePosition&lt;/a&gt; method to generate the new position for the draggable. To check custom bounds, I extended the generatePosition method and implemented by custom bounds checks in this. 
&lt;/p&gt;
```javascript
// Override the original _generatePosition in draggable to check for matrix bounds on drag.
dragContainer.draggable().data(&quot;draggable&quot;)._generatePosition = function(event) {
  return generatePositionsForDrag(dragContainer.draggable().data(&quot;draggable&quot;), event);
};
``` 
&lt;p&gt;First, we need to override the _generatePosition for our draggable element. Next, we will implement the new generate position similar to the one in draggable just using our bounds instead. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
* Generate new positions of the draggable element. This is used to override
* the original generate positions which had no way of specifying dynamic
* containment. This checks if the drag is valid by looking at the matrix
* coordinates and returns the new top and left positions accordingly.
*
* @param {Object} draggable - draggable object data.
* @param {Object} event - event that initiated the drag.
* @returns {Object} positions - new position of the draggable.
*/&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;generatePositionsForDrag&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; event&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; o &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;options&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scroll &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cssPosition &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;absolute&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollParent&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;!=&lt;/span&gt; document &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; $&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ui&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;contains&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollParent&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offsetParent&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offsetParent &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollParent&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scrollIsRootNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token regex&quot;&gt;/(html|body)/i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scroll&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tagName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; pageX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageX&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; pageY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageY&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; newPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    top&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            pageY															&lt;span class=&quot;token comment&quot;&gt;// The absolute mouse position&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;click&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top												&lt;span class=&quot;token comment&quot;&gt;// Click offset (relative to the element)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;relative&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top												&lt;span class=&quot;token comment&quot;&gt;// Only for relative positioned nodes: Relative offset from element to offset parent&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top												&lt;span class=&quot;token comment&quot;&gt;// The offsetParent&apos;s offset without borders (offset + border)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;jQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;safari &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; jQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;version &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;526&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cssPosition &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;fixed&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cssPosition &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;fixed&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollParent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollTop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; scrollIsRootNode &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; scroll&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollTop&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    left&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
            pageX															&lt;span class=&quot;token comment&quot;&gt;// The absolute mouse position&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;click&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left												&lt;span class=&quot;token comment&quot;&gt;// Click offset (relative to the element)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;relative&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left												&lt;span class=&quot;token comment&quot;&gt;// Only for relative positioned nodes: Relative offset from element to offset parent&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;offset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left												&lt;span class=&quot;token comment&quot;&gt;// The offsetParent&apos;s offset without borders (offset + border)&lt;/span&gt;
            &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;jQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;safari &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; jQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;browser&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;version &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;526&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cssPosition &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;fixed&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;cssPosition &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;fixed&apos;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollParent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollLeft&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; scrollIsRootNode &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; scroll&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;scrollLeft&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Impose contraints on newPosition to prevent crossing of matrix bounds. &lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Compute change in position for the drag.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; changeInPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    top&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_convertPositionTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;absolute&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;positionAbs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    left&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;_convertPositionTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;absolute&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;positionAbs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;checkPositionBounds&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; changeInPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; draggable&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * Checks the bounds for the matirx from four directions to find if the bounds are violated and returns the new positions.
 * @param  {Object} newPosition - The new position of the container for which to check the bounds.
 * @param  {Object} changeInPosition - The change in position. {top:0, left:0} can be passed here.
 * @param  {Object} draggable - The draggable instance.
 * @returns {Object} newPosition of the container.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;checkPositionBounds&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;newPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; changeInPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; draggable&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; firstRow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentCell&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;row &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; firstCol &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentCell&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;col &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Get element and container offsets&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; element &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_cellElements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;firstRow&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;firstCol&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; containerOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; _container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; elementOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If we are at the topmost cell, then check that bounds from the top are maintained.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentCell&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;row &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The new posoition.top of the first element relative to cotainter.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; top &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; changeInPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; elementOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; containerOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The drag crosses matrix bounds from the top.&lt;/span&gt;
      newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; top&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If we are at the leftmost cell, then check that bounds from the left are maintained.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentCell&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;col &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The new posoition.top of the first element relative to cotainter.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; changeInPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; elementOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; containerOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The drag crosses matrix bounds from the left.&lt;/span&gt;
      newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; left&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Get element offset for last element&lt;/span&gt;
  element &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;jQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_cellElements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;_cellElements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;_cellElements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  elementOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If we are at the bottomost cell, then check that bounds from the bottom are maintained.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentCell&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;row &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; _configuration&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getNumberOfBackgroundCells&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; _cellElements&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; _api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMatrixSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; containerBottom &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;containerOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; _container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; elementBottom &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;changeInPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; elementOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The new posoition.bottom of the last element relative to cotainter.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; bottom &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;  containerBottom &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; elementBottom&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;bottom &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The drag crosses matrix bounds from the bottom.&lt;/span&gt;
      newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; bottom&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If we are at the leftmost cell, then check that bounds from the left are maintained.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;_self&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentCell&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;col &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; _configuration&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getNumberOfBackgroundCells&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; _cellElements&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&gt;=&lt;/span&gt; _api&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getMatrixSize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// The new posoition.right of the first element relative to cotainter.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; containerRight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;containerOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; _container&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; newElementRight &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;changeInPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; elementOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; right &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;  containerRight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; newElementRight&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;right &lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// The drag crosses matrix bounds from the left.&lt;/span&gt;
      newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; right&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; newPosition&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p align=&quot;justify&quot;&gt;All you need to check your own bounds now for draggable is to implement your own checkPositionBounds and you are good to go. I almost decided to drop using the jQuery UI draggable and create my own. But in the end, a close look at the draggable code saved me the pain to write a custom draggable. So, now if you ever need to implement something complicated with jQuery UI widget, don&apos;t just try creating your own clone. The functionality might itself be buried into the code, you just need to figure out where to look. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Update UI for MacBook Pro Retina display]]></title><link>https://pulkitgoyal.in/update-ui-for-macbook-pro-retina-display</link><guid isPermaLink="false">https://pulkitgoyal.in/update-ui-for-macbook-pro-retina-display</guid><pubDate>Sat, 18 Aug 2012 08:48:08 GMT</pubDate><content:encoded>&lt;p&gt;Recently I purchased a MacBook Pro with Retina display and believe me Apple has done an incredible job with the next-gen MacBook Pro. The Retina display is a powerhouse. Almost everything else in native apps and photos looks amazingly crisp and clear on the Retina display. But for me as a developer when I started Eclipse first time, retina UI was not supporting Eclipse display very well. So here is the workaround to update UI:&lt;/p&gt;
&lt;p&gt;Go to &lt;code class=&quot;language-text&quot;&gt;Contents-&amp;gt;Info.plist&lt;/code&gt; by clicking on “Show package contents” on the Eclipse.app. Then Just above &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;dict&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;plist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Place this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;NSHighResolutionCapable&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;key&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, log out and restart the Eclipse. This also works for Aptana as well as for Titanium Studio and in general for all IDEs that are built on top of Eclipse.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Writing scalable recommender system with Hadoop]]></title><link>https://pulkitgoyal.in/writing-scalable-recommender-system-with-hadoop</link><guid isPermaLink="false">https://pulkitgoyal.in/writing-scalable-recommender-system-with-hadoop</guid><pubDate>Wed, 01 Aug 2012 22:39:33 GMT</pubDate><content:encoded>&lt;p&gt;Lets say we want to implement a very simple “people you might know” recommender algorithm. Obviously, the speed and scalability of such an algorithm is as important as the actual logic behind the algorithm because such algorithms generally run over a “huge” graph and implementing these normally would probably take a lot of time for recommending friends even for just one user. I will show how to implement a very naive recommender algorithm efficiently. The basic idea of the algorithm is that if person A and person B do not know each other but they have a lot of mutual friends, then the system should recommend that they connect with each other. We will do this is &lt;a href=&quot;https://hadoop.apache.org&quot;&gt;hadoop&lt;/a&gt; which is an open source software for highly reliable, scalable distributed computing. The main idea behind it is map and reduce jobs.
I assume that you are already familiar with these concepts (&lt;a href=&quot;https://hadoop.apache.org/common/docs/r0.20.2/mapred_tutorial.html&quot;&gt;tutorial&lt;/a&gt;). If not, I wouldn’t recommending reading this post further without having a look at what a mapper and reducer is.&lt;/p&gt;
&lt;p&gt;In order to recommend such friends, we first need to count the number of mutual friends that each pair of persons have in such a network. For this, we will need a map reduce job that functions similar to the map-reduce job for finding the frequency of words in a file. For every pair of friends in a list, we output the following tuple: &amp;#x3C;[friend1 friend2 1], 1&gt; . In addition to this, we also output a tuple &amp;#x3C;[source friend -1], -1&gt; for every pair of persons who are friends.
i.e. For an input:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;source &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;“friend1”&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; “friend2”&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; “friend3”&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;the mapper outputs&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; friend1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; friend2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; friend3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;friend1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; friend2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;friend1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; friend3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;friend2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; friend3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we need to define our equals() method such that it can looks at the two names in the key to find equal keys. We also need to define our Comparator such that it sorts the keys based on the third attribute in the key.
Therefore, the reducer gets as input a key denoting a pair of friends along with the list of their number of common friends. In the reduce function, we can check if the first record has a -1 in the key. If there is such a record, we can ignore that pair of friends because they already have a direct connection between them. Finally, we aggregate the values for all the keys in the reducer and output the tuple &amp;#x3C;[friend1, friend2], numberOfMutualFriends&gt; for all the pairs of friends which don’t have third attribute as -1 in the key.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  split input to obtain source and friends&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    f1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; friends&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
    output &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;source&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; f1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;j &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      f2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; friends&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;j&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
      output &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;f1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; f2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;
    end
  end
end

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key1&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; key2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; key1&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; key2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; key1&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; key2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; key1&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; key2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  end
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
end

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compare&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;key1&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; key2&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
end

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;key&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; values&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;values&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  end
  numberOfCommonFriends &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;value v &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; values&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    numberOfCommonFriends &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  end
  output &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;key&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; key&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; numberOfCommonFriends&lt;span class=&quot;token operator&quot;&gt;&gt;&lt;/span&gt;
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After the first map-reduce job, we obtain a list of pair of persons along with the number of common friends that they have. Our final map-reduce job looks at this list and outputs a list of persons they have maximum number of common friends with. Hence, our map job just outputs&amp;#x3C;[pair[1], numberOfCommonFriends], pair[2]&gt; and&amp;#x3C;[pair[2], numberOfCommonFriends], pair[1]&gt;. Our equals() method would look at the person in the key to find equal keys and our comparator would look at the numberOfCommonFriends to sort the keys. This would ensure that the tuples for the same person go to the same reducer and in a sorted order by the number of common friends. Our reducer then just needs to look at the top 10 values and output the list.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;function map(input)
  split input to obtain friend1, friend2 and numberOfCommonFriends
  output &amp;lt;[friend1, numberOfCommonFriends], friend2&amp;gt;
  output &amp;lt;[friend2, numberOfCommonFriends], friend1&amp;gt;
end

function equals(key1, key2)
  if (key1[1] == key2[1])
    return true;
  end
  return false;
end

function compare(key1, key2)
  return (key1[2] &amp;lt; key2[2]);
end

function reduce(key, values)
  suggestions = []
  for (i = 1:min(10,size(values)))
    suggestions.push(values[i]);
  end
  output &amp;lt;key[1], suggestions&amp;gt;
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is all we need to do to have our small recommender system up and running on Hadoop which will already scale quite well. There are still plenty of things that can be done here both in the algorithm as well as the implementation to improve the results and scalability.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Link order for libraries C and C++]]></title><link>https://pulkitgoyal.in/link-order-for-libraries-c-and-c</link><guid isPermaLink="false">https://pulkitgoyal.in/link-order-for-libraries-c-and-c</guid><pubDate>Tue, 31 Jul 2012 21:30:24 GMT</pubDate><content:encoded>&lt;p&gt;There are several advantages of using external libraries in &lt;code class=&quot;language-text&quot;&gt;C&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;C++&lt;/code&gt;. It saves a lot of effort as there are several wonderful C++ libraries out there to do just about anything. But there is one problem that many beginners face when beginning to use libraries. &lt;code class=&quot;language-text&quot;&gt;undefined reference to &amp;lt;function&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lets say we have a program that uses functions defined in an external library mylib. We can link it by adding -lmylib when we compile our code. So we do this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;g++ -lmylib main.c -o main    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;incorrect order&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;

main.o: In &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;main&apos;:
main.o&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;.text+0xf&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;: undefined reference to &lt;span class=&quot;token variable&quot;&gt;`&lt;/span&gt;&lt;/span&gt;myfunc&apos;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;But mylib is linked and it has a definition for myfunc. The problem here is that the order of linking is important. The traditional behavior of linkers is to search for external functions from left to right in the libraries specified on the command line. This means that a function in libraryA is referenced from libraryB, libraryA should be linked after libraryB. This might often lead to circular dependencies when a library uses some function from another library which in turn uses a function from the first library. For example, if foo uses a function defined in bar and bar uses a function defined in foo, we would need to write:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;g++ -o main -lfoo -lbar -lfoo&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Although, this works well in practice and is used quite frequently, a much better solution to the above problem is to use the linker’s —start-group and —end-group options, like this:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;g++ -o main -Wl,--start-group -lfoo -lbar -Wl,--end-group&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Documenting jQuery plugins with jsdoc-toolkit]]></title><link>https://pulkitgoyal.in/documenting-jquery-plugins-jsdoc-toolkit</link><guid isPermaLink="false">https://pulkitgoyal.in/documenting-jquery-plugins-jsdoc-toolkit</guid><pubDate>Mon, 04 Jun 2012 07:09:24 GMT</pubDate><content:encoded>&lt;p&gt;Documenting a code is very important, specially when you are working in a team. For java, JavaDoc has been my favorite. But there seems to be a lack of documentation tools for Javascript. The one that I found most easy to use (transitioning from JavaDoc) was &lt;a href=&quot;https://code.google.com/p/jsdoc-toolkit/&quot;&gt;jsdoc-toolkit&lt;/a&gt;. But since there was no good tutorial for how to begin documenting jQuery plugins with jsdoc, I decided to write one.&lt;/p&gt;
&lt;p&gt;Installation in Ubuntu is simple. Just use apt-get install.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token function&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;apt-get&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; jsdoc-toolkit&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I won’t go into the details for other platforms but it should be pretty simple to install on other platforms as well. To generate the documentation, use:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;jsdoc -d&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;./doc ./src&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This would generate the documentation in doc directory for the files in src. The main issues start from here because when you try to document your jQuery plugin using this, it doesn’t recognize the friendly $. Nor does it know what jQuery is.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Trying to document jMatrixBrowse as a member of undocumented symbol jQuery
Trying to document jMatrixBrowse as a member of undocumented symbol jQuery.fn&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;Trying to document jMatrixBrowse as a member of undocumented symbol $
Trying to document jMatrixBrowse as a member of undocumented symbol $.fn&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There is a simple way to tell this to it. Just write these comments at the top of the file where you would like to use jQuery.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * See (https://jquery.com/).
 * @name jQuery
 * @class
 * See the jQuery Library  (https://jquery.com/) for full details.  This just
 * documents the function and classes that are added to jQuery by this plug-in.
 */&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;/**
 * See (https://jquery.com/)
 * @name fn
 * @class
 * See the jQuery Library  (https://jquery.com/) for full details.  This just
 * documents the function and classes that are added to jQuery by this plug-in.
 * @memberOf jQuery
 */&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This tells jsdoc about jQuery and jQuery.fn and you can then begin writing documentation for your plugin.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
   * myAwesomePlugin - an awesome jQuery plugin.
   *
   * @class myAwesomePlugin
   * @memberOf jQuery.fn
   */&lt;/span&gt;
  jQuery&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fn&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;myAwesomePlugin&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can also write a file overview to be included in the documentation by writing this at the top.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * @fileOverview Contains the awesome plug-in code.
 * @version 0.1
 * @author Pulkit Goyal &amp;lt;pulkit110@gmail.com&gt;
*/&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The detailed documentation for functions is very similar to JavaDoc style. Here’s a sample.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * Get user defined options from data-* elements.
 * @param {jQuery object} elem - the element to retrieve the user options from.
 * @returns {Object} options - User&apos;s options for the plugin.
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getUserOptions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;elem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[HackerNews in 3D]]></title><link>https://pulkitgoyal.in/hackernews-3d</link><guid isPermaLink="false">https://pulkitgoyal.in/hackernews-3d</guid><pubDate>Mon, 09 Apr 2012 21:22:14 GMT</pubDate><content:encoded>&lt;p&gt;Today I noticed the 3D Inspect element feature for Firefox.&lt;/p&gt;
&lt;p&gt;Here’s how you can get it:
Step 1: Make sure you have the latest version (at least 11.0). Get the latest version &lt;a href=&quot;https://www.mozilla.org/en-US/firefox/new/&quot; title=&quot;Firefox&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Step 2: Right click anywhere in the page then click Inspect Element (Q).&lt;/p&gt;
&lt;p&gt;Step 3: At the bottom of the page click the 3D (M) button.&lt;/p&gt;
&lt;p&gt;Its a great way to show off Firefox’s 3D capabilities. But I haven’t been able to find where this can be useful. Don’t forget to leave comments about what you think of this feature and where it can be useful as compared to the traditional inspect element.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Similarity Metrics on Twitter]]></title><link>https://pulkitgoyal.in/similarity-metrics-twitter</link><guid isPermaLink="false">https://pulkitgoyal.in/similarity-metrics-twitter</guid><pubDate>Fri, 16 Mar 2012 23:01:03 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Most of the researches in the field of community detection consider only social connections as the similarity measure for obtaining communities in the network. In this post (as a part of my series of posts on Data Mining and Analysis on Twitter), we will discuss about various other possible similarity measures between different users and discuss why and how they can be used to cluster users in the network.
&lt;/p&gt;&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;User Connections&lt;/strong&gt;: This is the similarity measure that is used the most in the literature to define a connection between two users. We define a social connection on Twitter to be a following or a being followed relationship between two users on twitter. As we will see in further sections, this is one of the most dominating factors that produce a community structure on twitter and this is the reason that it has been used so extensively in most of the researches. We define an edge of weight between two users &amp;#xA0;and &amp;#xA0;if either &amp;#xA0;follows &amp;#xA0;or &amp;#xA0;follows . Therefore, the users social connections (or the user connections matrix as we will call it now) is a symmetric matrix with a link between two users who have either of the following or being followed relation between them.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;User Mentions&lt;/strong&gt;: This is another form of a connection that can be defined between two users. As described before, mention is the event of mentioning another user in our tweet. The image below shows an example of a mention on twitter. The user named &lt;a href=&quot;https://twitter.com/#!/EPFLNews&quot; target=&quot;_blank&quot;&gt;@EPFLNews&lt;/a&gt; has mentioned another user named &lt;a href=&quot;https://twitter.com/#!/SmallRivers&quot; target=&quot;_blank&quot;&gt;@SmallRivers&lt;/a&gt;. This mention is as a result of &lt;a href=&quot;https://twitter.com/#!/EPFLNews&quot; target=&quot;_blank&quot;&gt;@EPFLNews&lt;/a&gt;&amp;#xA0;saying something about the user &lt;a href=&quot;https://twitter.com/#!/SmallRivers&quot; target=&quot;_blank&quot;&gt;@SmallRivers&lt;/a&gt; and therefore wanted to let him know. It has been observed that a mention occurs as a result of discussion or good relationship between users and therefore, it can serve as a good measure of relationship between users. Another important motivation to consider mention as a similarity measure is that it corresponds closely to user connections but is much more selective. We count the number of mentions that two users make on twitter and assign the weight of the link between two users &amp;#xA0;and &amp;#xA0;as the total number of tweets posted by &amp;#xA0;that mention &amp;#xA0;and the tweets posted by &amp;#xA0;that mention the user .&lt;/li&gt;
&lt;/ul&gt;
&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1392235501/mention_kf7u66.png&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-507&quot; title=&quot;mention&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_54,w_300/v1392235501/mention_kf7u66.png&quot; alt width=&quot;300&quot; height=&quot;54&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot; align=&quot;center&quot;&gt;An example tweet showing a mention on twitter&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Description&amp;#xA0;Content Similarity&lt;/strong&gt;: Users on twitter can post a description about themselves which is shown in their profile. The image below shows an example of description on twitter for the user with screen name &lt;a href=&quot;https://twitter.com/pulkit110&quot; target=&quot;_blank&quot;&gt;@pulkit110&lt;/a&gt;. This description can sometimes be used to measure the similarity between users on twitter. Since this description generally describes the keywords about what the user likes to do or where he works/studies at, it can serve as a very good suggestion of user similarity on twitter. Therefore, we consider the cosine similarity between the users&amp;#x2019; descriptions as one of the similarity measures in determining the clusters of users on twitter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1392235500/description_ei5ol0.png&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-508&quot; title=&quot;description&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_78,w_300/v1392235500/description_ei5ol0.png&quot; alt width=&quot;300&quot; height=&quot;78&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;Example of user description on Twitter&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;Tweet Content Similarity&lt;/strong&gt;: The most popular concept of twitter is the concept of tweets. It is tweets that most users on twitter are interested in and therefore, it can be used as a similarity measure between different users. We define the tweet similarity between two users as the cosine similarity between the documents formed by combining the tweets of a user into one. The text similarity measure between the tweets helps us to observe if the users are interested in talking about similar topics. If the users talk about the same topic then it is quite possible that they are interested in similar things and is an indication of good similarity between them.&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Hash tag similarity between users&lt;/strong&gt;: Hashtag is a unique concept on twitter which allows users to specify important keywords in their tweets my prefixing &amp;#x2018;#&amp;#x2019; before a keyword in a tweet. Hashtags have been used on twitter to set trending topics as well as start chat rooms etc. The hash tags allow users to specify what they think as an important keyword in their tweet and therefore can be considered as a very strong factor to compare two users&amp;#x2019; similarity. The image below shows an example of the user &lt;a href=&quot;https://twitter.com/diwakarsapan&quot; target=&quot;_blank&quot;&gt;@diwakarsapan&lt;/a&gt; posting a tweet with hashtag &lt;a href=&quot;https://twitter.com/#!/search/realtime/%23IEUsers&quot; target=&quot;_blank&quot;&gt;#IEUsers&lt;/a&gt;. The hashtag shows that the user wants to emphasize on a particular keyword in his tweet. We define the hash tag similarity between two users as the cosine similarity between the collections of hashtags of the different users.&lt;/li&gt;
&lt;/ul&gt;
&lt;p align=&quot;center&quot;&gt;&lt;a href=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/v1392235502/hashtag_hc6htv.png&quot;&gt;&lt;img class=&quot;alignnone size-medium wp-image-506&quot; title=&quot;hashtag&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_65,w_300/v1392235502/hashtag_hc6htv.png&quot; alt width=&quot;300&quot; height=&quot;65&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center;&quot;&gt;Example of hash tag on twitter&lt;/p&gt;
&lt;div&gt;&lt;/div&gt;
&lt;p&gt;All posts in this series:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.sapandiwakar.in/academics/analysis-of-fast-modularity-clustering-on-twitter/&quot; title=&quot;Analysis of Fast Modularity Clustering on Twitter&quot;&gt;Analysis of Fast Modularity Clustering on Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://pulkitgoyal.in/2012/03/16/analysis-spectral-clustering-twitter/&quot; title=&quot;Analysis of Spectral Clustering on Twitter &quot;&gt;Analysis of Spectral Clustering on Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.sapandiwakar.in/academics/predicting-future-mentions-on-twitter/&quot; title=&quot;Predicting future mentions on Twitter &quot;&gt;Predicting future mentions on Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://pulkitgoyal.in/2012/03/17/similarity-metrics-twitter/&quot; title=&quot;Similarity Metrics on Twitter&quot;&gt;Similarity Metrics on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[Analysis of Spectral Clustering on Twitter]]></title><link>https://pulkitgoyal.in/analysis-spectral-clustering-twitter</link><guid isPermaLink="false">https://pulkitgoyal.in/analysis-spectral-clustering-twitter</guid><pubDate>Fri, 16 Mar 2012 21:02:38 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;I recently worked on Data Mining and Analysis on Twitter as my semester project at EPFL. During the 4 months that we worked on the project, we were able to achieve many goals. In this post, I will be describing how we can cluster a small group of users on Twitter based on different similarity metrics and a brief comparison of several clustering methods that could be used for this.
&lt;p align=&quot;justify&quot;&gt;For this analysis, we used three different user lists on twitter as the ground truth data for a group of about five hundred users. We obtained all the tweets from the users who were listed in the three lists and then tried to obtain clusters by using different similarity metrics using the spectral clustering algorithm. In addition to this, we also explore different connections between users in addition to just the social connections in order to find out other features that affect the users being listed together. We present results of applying spectral clustering algorithm using the modularity matrix and the symmetric normalized Laplacian matrix. We compare the results of these approaches while using several different input matrices formed by different combination of the above similarity measures.
&lt;blockquote&gt;If we have a set of n objects $$x_1,x_2,x_3,\dots,x_n$$ with a pairwise similarity function defined between them which are symmetric and non-negative. Spectral clustering is the set of methods and techniques that partition the set into clusters by using the eigenvectors of matrices.&lt;/blockquote&gt;
&lt;p align=&quot;justify&quot;&gt;The motivation behind using eigenvectors for clustering is that the change of representation induced by the eigenvectors makes the cluster properties of the initial data set much more evident. In this way, spectral clustering is able to separate data points that could not be resolved by applying directly k-means clustering, for instance, as the latter tends to deliver convex sets of points. Since the introduction of spectral methods in &quot;&lt;a title=&quot;Lower Bounds for the Partitioning of Graphs&quot; href=&quot;https://domino.research.ibm.com/tchjr/journalindex.nsf/c469af92ea9eceac85256bd50048567c/3e52839ce8b7e98885256bfa006841bd!OpenDocument&quot; target=&quot;_blank&quot;&gt;Lower Bounds for the Partitioning of Graphs&lt;/a&gt;&quot; there have been several researches where scientists have tried using different matrices for the calculation of eigenvectors followed by applying clustering on the eigenvectors. A complete discussion about the different spectral algorithms and matrices would take a new post, so I wouldn&apos;t go into much details here.
&lt;p align=&quot;justify&quot;&gt;Now, I will present the results of applying spectral clustering algorithm using the modularity matrix and the symmetric normalized Laplacian matrix. We compared the results of these approaches while using several different input matrices formed by different combination of the above similarity measures. Before I begin, let&amp;apos;s have a look at the &lt;a title=&quot;Sparse Matrices Matlab&quot; href=&quot;https://www.mathworks.ch/products/matlab/demos.html?file=/products/demos/shipping/matlab/sparsity.html&quot; target=&quot;_blank&quot;&gt;spy plot &lt;/a&gt;of the user connections.
&lt;img src=&quot;https://pulkitgoyal.in/wp-content/uploads/2012/03/spyUserConnections501.png&quot; alt=&quot;Spy plot of user connections&quot;&gt;
The users have been ordered by the lists that they belong to and therefore, we can immediately observe three communities present in the network by looking at the plot.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;We present the results of application of the algorithm on users’ social connections as well as several other individual similarity measures (user mention similarity, description content similarity and tweet content similarity) followed by a simple combination of the different similarity measures. For finding the combined similarity measure, we sum all the different similarity measures. Since the different similarity measures can be on different scales, these similarity measures are normalized before we add them together and apply the clustering algorithms. Therefore, the adjacency matrix that corresponds to the combined similarity measures is the sum of all the individual normalized adjacency matrices.
&lt;p align=&quot;justify&quot;&gt;In order to measure the accuracy of our clustering algorithms, we use several different cluster evaluation objective functions to compare obtained clusters with the ground truth data of clusters which represents the distribution of the users into different lists. I will present the values of &lt;a title=&quot;Evaluation of clustering&quot; href=&quot;https://nlp.stanford.edu/IR-book/html/htmledition/evaluation-of-clustering-1.html&quot; target=&quot;_blank&quot;&gt;Normalized Mutual Information and RandIndex&lt;/a&gt; during the analysis. A higher value of these factors means a better correspondence with ground truth. The table at the end of this post summarizes these values for different clustering algorithms and similarity metrics.
&lt;p align=&quot;justify&quot;&gt;I will now show some visualizations of our obtained results. The results have been obtained using Gephi  for visualization. The communities are represented by different colours in the visualizations. Note that the arrangement of the nodes in the space doesn’t represent any communities. The arrangement of nodes in the visualizations corresponds to a layout. We keep the same layout for all the visualizations so that it is easy to see the results of the clustering process. The different clusters in the visualizations are represented by different colours. This means that all the nodes in the visualization that have the same colour have been placed into one cluster for that visualization. Figure (a) shows the communities formed using the ground truth data. Figure (b) shows the clusters obtained for the network using the user connections as the only similarity measure using the modularity matrix for spectral clustering. Figure (c) shows the results of community detection using the combination of all similarity measures for the modularity matrix. Finally Figure (d) shows the results for community detection applied on combined similarity measures using the Symmetric Normalized Laplacian matrix.
&lt;p&gt;  a&lt;img src=&quot;https://pulkitgoyal.in/wp-content/uploads/2012/03/501GroundTruth.png&quot; alt=&quot;Ground truth clusters (based on user lists)&quot; height=&quot;256&quot; width=&quot;256&quot;&gt;   b&lt;img src=&quot;https://pulkitgoyal.in/wp-content/uploads/2012/03/501ConnectionModularity.png&quot; alt=&quot;Clusters obtained using only users&amp;apos; social connections for Laplacian based clustering&quot; height=&quot;256&quot; width=&quot;256&quot;&gt;&lt;/p&gt;
&lt;p&gt;  c&lt;img src=&quot;https://pulkitgoyal.in/wp-content/uploads/2012/03/501AllModularity.png&quot; alt=&quot;Clusters obtained using combined similarity measures for Modularity based clustering&quot; height=&quot;256&quot; width=&quot;256&quot;&gt;  d&lt;img src=&quot;https://pulkitgoyal.in/wp-content/uploads/2012/03/501AllLaplacian.png&quot; alt=&quot;Clusters obtained using combined similarity measures for Laplacian based clustering&quot; height=&quot;256&quot; width=&quot;256&quot;&gt;&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;We can observe that user’s social connections are the most dominating factors for this group of users while dividing the users into different communities. We can also observe that the high values of benchmark results correspond to the good community detection that corresponds closely to the ground truth data by looking at the visualizations in Figure (a) and Figure (b) which show the ground truth clusters and the clusters obtained by applying community detection using modularity matrix on social connections respectively. The other individual similarity measures like the user mentions, tweet content similarity and description content similarity don’t perform very well when used for community detection using the modularity matrix. We also observe that the results for combined similarity measures, i.e. the sum of connections, mentions, tweet content similarity and description content similarity doesn’t perform as well as the connections. This means that the addition of low information contents like the mentions, tweet content similarity and description content similarity decreases the accuracy of the clustering algorithm even in the presence of the highly informative social connections. A reason for the bad performance of the similarity measures based on the tweets, descriptions and mentions can be that the group of users are similar and generally post similar content on the web. This also means that the user behaviours don’t seem to be consistent with the ground truth data.
&lt;p align=&quot;justify&quot;&gt;However, the detection of communities for the user’s social connections using the Symmetric Normalized Laplacian matrix fails. This is because the Laplacian based methods are known to be quite sensitive to the presence of disconnected nodes in the graph. Therefore, the results of the social connections for the Symmetric Normalized Laplacian are similar to the other individual results which mean that we are not able to reconstruct any valuable cluster information when using the Normalized Laplacian. But the combined matrix performs consistently even when using the Normalized Laplacian for community detection. This is because addition of several different kinds of information to the social connections makes it a connected graph and therefore, we now observe results consistent with the ones obtained while using modularity matrix for community detection.
&lt;p align=&quot;justify&quot;&gt;Therefore, we can conclude from these results that user connections are a very good measure of information and for this model; they give the best clustering results when used with the modularity matrix for spectral clustering. We can also see that adding several other non-informative measures to this layer decreases the accuracy considerably when used with the modularity matrix. However, an interesting observation occurs from our discussion and results regarding the Symmetric Normalized Laplacian matrix that even a highly informative layer (user connections) can prove to be a very bad indication of clustering if not used with the correct clustering algorithm due to the presence of disconnected nodes in the graph. We also found that even adding a non-informative (or slightly informative) layer as in this case can improve the connectivity and therefore improve the clustering results.
&lt;table width=&quot;621&quot; border=&quot;1&quot; cellspacing=&quot;0&quot; cellpadding=&quot;0&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td rowspan=&quot;2&quot; width=&quot;206&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;strong&gt;Similarity Matrix&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td colspan=&quot;2&quot; width=&quot;217&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;strong&gt;Modularity Matrix&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;td colspan=&quot;2&quot; width=&quot;198&quot;&gt;
&lt;p align=&quot;center&quot;&gt;&lt;strong&gt;Symmetric Normalized Laplacian Matrix&lt;/strong&gt;&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;113&quot;&gt;
&lt;p align=&quot;center&quot;&gt;NMI&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;RI&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;NMI&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;94&quot;&gt;
&lt;p align=&quot;center&quot;&gt;RI&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;206&quot;&gt;
&lt;p align=&quot;center&quot;&gt;User Connections&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3868&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.7174&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0077&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;94&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3374&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;206&quot;&gt;
&lt;p align=&quot;center&quot;&gt;Mention&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0130&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3398&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0077&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;94&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3374&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;206&quot;&gt;
&lt;p align=&quot;center&quot;&gt;Tweet content similarity&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0074&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3371&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0077&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;94&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3374&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;206&quot;&gt;
&lt;p align=&quot;center&quot;&gt;Description content Similarity&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0780&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.5254&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.0088&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;94&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.3381&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td width=&quot;206&quot;&gt;
&lt;p align=&quot;center&quot;&gt;All combined&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;113&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.2500&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.6175&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;104&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.2931&lt;/p&gt;
&lt;/td&gt;
&lt;td width=&quot;94&quot;&gt;
&lt;p align=&quot;center&quot;&gt;0.6472&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;All posts in this series:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.sapandiwakar.in/academics/analysis-of-fast-modularity-clustering-on-twitter/&quot; title=&quot;Analysis of Fast Modularity Clustering on Twitter&quot;&gt;Analysis of Fast Modularity Clustering on Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://pulkitgoyal.in/2012/03/16/analysis-spectral-clustering-twitter/&quot; title=&quot;Analysis of Spectral Clustering on Twitter &quot;&gt;Analysis of Spectral Clustering on Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.sapandiwakar.in/academics/predicting-future-mentions-on-twitter/&quot; title=&quot;Predicting future mentions on Twitter &quot;&gt;Predicting future mentions on Twitter&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://pulkitgoyal.in/2012/03/17/similarity-metrics-twitter/&quot; title=&quot;Similarity Metrics on Twitter&quot;&gt;Similarity Metrics on Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[File download using HTTP request]]></title><link>https://pulkitgoyal.in/file-download-http-request</link><guid isPermaLink="false">https://pulkitgoyal.in/file-download-http-request</guid><pubDate>Tue, 14 Feb 2012 15:16:01 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Downloading a file from a server is trivial and so is the implantation of it using &lt;a href=&quot;https://docs.oracle.com/javaee/5/api/javax/servlet/http/HttpServletResponse.html&quot; target=&quot;_blank&quot;&gt;httpservletresponse&lt;/a&gt;. But after fighting with for a long time I finally came across &lt;a href=&quot;https://filamentgroup.com/lab/jquery_plugin_for_requesting_ajax_like_file_downloads/&quot; target=&quot;_blank&quot;&gt;this&lt;/a&gt; jQuery plugin. This works well as long as we make HTTP request using GET or POST to server and the server responds with a file to download.
&lt;h3&gt; How to use this &lt;/h3&gt;
For this you need to download the &lt;a href=&quot;https://github.com/filamentgroup/jQuery-File-Download&quot; target=&quot;_blank&quot;&gt;plugin&lt;/a&gt; and include the file-
```javascript
&lt;script type=&quot;text/javascript&quot; src=&quot;path-to-js-file.js&quot;&gt;&lt;/script&gt;
```
&lt;p align=&quot;justify&quot;&gt;The plugin accepts 3 arguments for url, data, and method. You can pass data to these arguments just as you would to jQuery&apos;s $.post or $.get functions, and assuming the server has no problems handling the request, the front end will respond with a prompt for a file download and the user never needs to leave the page. Here&apos;s an example call to the plugin:
```javascript
// the second argument can&apos;t be left blank, so if you don&apos;t need it, you can write anything
$.download(&apos;get&apos;, &apos;file=file&apos;, &apos;get&apos;);
```
&lt;p&gt;and you’re done!&lt;/p&gt;
&lt;p&gt;Of course, if the server doesn’t send the correct response, it wouldn’t work. These are the list of headers that I used for the response sent from the server.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// get your file as InputStream&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;InputStream&lt;/span&gt; is &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// copy it to response&apos;s OutputStream&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;IOUtils&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;is&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getOutputStream&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;flushBuffer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// set headers&lt;/span&gt;
response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setContentType&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;application/pdf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Your content type&lt;/span&gt;
response&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setHeader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Content-Disposition&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot;attachment; filename=somefile.pdf&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Using Hibernate to filter results by Date]]></title><link>https://pulkitgoyal.in/hibernate-filter-results-date</link><guid isPermaLink="false">https://pulkitgoyal.in/hibernate-filter-results-date</guid><pubDate>Sun, 22 Jan 2012 14:28:56 GMT</pubDate><content:encoded>&lt;p&gt;Today, I was trying to access some data for my project on Twitter and filtering it using the creation date of the tweets. So I began by creating the usual &lt;code class=&quot;language-text&quot;&gt;Criteria&lt;/code&gt; and added a few Restrictions. For filtering by date, I created Date objects for &lt;code class=&quot;language-text&quot;&gt;startDate&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;endDate&lt;/code&gt; using &lt;code class=&quot;language-text&quot;&gt;Calendar.getTime()&lt;/code&gt; method and added the following &lt;code class=&quot;language-text&quot;&gt;Restriction&lt;/code&gt;,    &lt;code class=&quot;language-text&quot;&gt;c.add(Restrictions.between(&amp;quot;createdAt&amp;quot;, startDate, endDate);&lt;/code&gt;
Surprisingly, this didn’t work as I had expected and I was getting an empty result. I Googled for it but couldn’t find much. The only thing was that the Restriction should work given the date. Well, I was in a hurry and didn’t try to dig it through. As a workaround, I tried writing HQL query to get the results but that didn’t work either. &lt;/p&gt;
&lt;p&gt;This is what worked. I created the date using &lt;code class=&quot;language-text&quot;&gt;SimpleDateFormat&lt;/code&gt; and parsing the date. Here’s what I did:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;java&quot;&gt;&lt;pre class=&quot;language-java&quot;&gt;&lt;code class=&quot;language-java&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;SimpleDateFormat&lt;/span&gt; format &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SimpleDateFormat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;yyyy-MM-dd hh:mm:ss&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt; startDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; format&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2011-11-09 00:00:00&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token class-name&quot;&gt;Date&lt;/span&gt; endDate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; format&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;2011-11-017 00:00:00&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

c&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Restrictions&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;between&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;createdAt&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startDate&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endDate&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;	

&lt;span class=&quot;token class-name&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;token generics&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;StatusDto&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt; statuses &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c1&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;list&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// It works fine now&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Its a quick hack and did work out for me. I was in bit of a hurry and didn’t try to dig up the reason for it now working earlier. Maybe, someone can point my mistake out in the comment. Anyway, I will update the post if I find the reason for it. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Stack Overflow like keyboard buttons in post]]></title><link>https://pulkitgoyal.in/stack-overflow-keyboard-buttons-post</link><guid isPermaLink="false">https://pulkitgoyal.in/stack-overflow-keyboard-buttons-post</guid><pubDate>Mon, 02 Jan 2012 23:01:46 GMT</pubDate><content:encoded>&lt;style type=&quot;text/css&quot;&gt;
kbd {
	padding: 2px 4px;
	white-space: nowrap;
	color: black;
	background: #EEE;
	border-width: 1px 3px 3px 1px;
	border-style: solid;
	border-color: #CCC #AAA #888 #BBB;
}
&lt;/style&gt;
&lt;p align=&quot;justify&quot;&gt;Here&apos;s a quick hack to get yourself one of those Stack Overflow like keyboard buttons. For those of you who don&apos;t know what these are, have a look &lt;a href=&quot;https://stackoverflow.com/a/1402383/643109&quot; title=&quot;Stack Overflow Keyboard button example&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. I am writing this blog post while I wait for the India Australia cricket &lt;a href=&quot;https://www.espncricinfo.com/australia-v-india-2011/engine/current/match/518951.html&quot; title=&quot;India vs Australia 2012&quot; target=&quot;_blank&quot;&gt;match&lt;/a&gt; to begin which is in a few minutes from now, so I&apos;ll be quick :).&lt;/p&gt;
&lt;p&gt;To add these cool looking keys in your post, just write them in &lt;code class=&quot;language-text&quot;&gt;&amp;lt;kbd&amp;gt;...&amp;lt;/kbd&amp;gt;&lt;/code&gt; tags. Simple, right? Not quite. We’re not done yet. We need to do just one more thing. Add the following in your stylesheet:&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;And we are done. Give it a try. These look wonderful to me. Here&apos;s an example:
&lt;kbd&gt;Ctrl&lt;/kbd&gt; + &lt;kbd&gt;D&lt;/kbd&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;kbd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;padding&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 2px 4px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;white-space&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; nowrap&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; black&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;background&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #EEE&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;border-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1px 3px 3px 1px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;border-style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; solid&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;token property&quot;&gt;border-color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; #CCC #AAA #888 #BBB&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;hr/&gt;
&lt;p align=&quot;justify&quot;&gt;Here&apos;s a small keyboard built using these buttons :)&lt;/p&gt;
&lt;p&gt;&lt;kbd&gt;&amp;nbsp;~&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;1&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;2&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;3&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;4&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;5&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;6&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;7&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;8&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;9&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;0&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;-&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;=&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;Backspace&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;/p&gt;
&lt;p&gt;&lt;kbd&gt;Tab&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;q&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;w&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;e&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;r&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;t&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;y&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;u&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;i&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;o&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;p&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;[&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;]&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;ENTER&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;/p&gt;
&lt;p&gt;&lt;kbd&gt;Caps&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;a&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;s&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;d&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;f&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;g&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;h&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;j&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;k&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;l&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;;&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;´&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;+&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;/p&gt;
&lt;p&gt;&lt;kbd&gt;Shift&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;&amp;lt;&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;z&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;x&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;c&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;v&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;b&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;n&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;m&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;,&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;.&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;/&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;Shift&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;/p&gt;
&lt;p&gt;&lt;kbd&gt;Ctrl&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;Win&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;Alt&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Space&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;Alt&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;Win&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;Menu&amp;nbsp;&lt;/kbd&gt;&lt;kbd&gt;&amp;nbsp;Ctrl&amp;nbsp;&lt;/kbd&gt;&lt;/p&gt;
&lt;hr/&gt;</content:encoded></item><item><title><![CDATA[Testing your web project using jqUnit]]></title><link>https://pulkitgoyal.in/testing-web-project-jqunit</link><guid isPermaLink="false">https://pulkitgoyal.in/testing-web-project-jqunit</guid><pubDate>Fri, 30 Dec 2011 23:48:48 GMT</pubDate><content:encoded>&lt;p&gt;I have been wanting to write this post since a long time. Finally, here it comes. &lt;/p&gt;
&lt;p&gt;This is something that everyone working in a community should know. Testing! I didn’t consider it important enough until Michelle explained its  importance to me during the Image Editor project for Google Summer of Code. Now that I started using it, its become so important that its hard to imagine a project with a team without test cases. And the most important thing is writing these tests is amazingly simple and it saves you a lot of time in the future. &lt;/p&gt;
&lt;p&gt;I will put up the importance very briefly here. When we develop anything in a team with more than one developer working on the same project, there may be some changes that we make that might break something that others had previously written because they had assumed something which wasn’t very obvious to us. Having tests ready for the project comes to our rescue here. If the tests pass, we can lie in peace knowing that the changes that we have made don’t break anything.&lt;/p&gt;
&lt;p&gt;As I mentioned earlier, writing test-cases is amazingly simple using all those frameworks out there. I will be describing the process of writing tests for jQuery using jqUnit. Before, we start writing the test, this is how we can initialize a new test case: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; myTests &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;jqUnit&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;TestCase&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;My Application Tests&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;We can now start writing our tests: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascipt&quot;&gt;&lt;pre class=&quot;language-javascipt&quot;&gt;&lt;code class=&quot;language-javascipt&quot;&gt;// 1
myTests.test(&amp;quot;Test Scenario 1&amp;quot;, function () {
	// Write some tests here
});&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now lets start writing some simple tests. Don’t worry. Writing unit tests requires us to just call a few functions that we wrote and check it against a return value that we expect. This is something that you always think of when writing the function, so writing the test is just a little extra effort which certainly pays off in the future. Finally, here’s how to write the tests: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascipt&quot;&gt;&lt;pre class=&quot;language-javascipt&quot;&gt;&lt;code class=&quot;language-javascipt&quot;&gt;jqUnit.isVisible(&amp;quot;My component is visible&amp;quot;, &amp;quot;#my-component-id&amp;quot;);
jqUnit.notVisible(&amp;quot;My hidden component is not visible&amp;quot;, &amp;quot;#my-hidden-component-id&amp;quot;);
jqUnit.assertNotNull(&amp;quot;My function 1 doesn&amp;#39;t return null&amp;quot;, myApplicationInstance.myFunction1());
jqUnit.assertNotUndefined(&amp;quot;My function 1 doesn&amp;#39;t return undefined value&amp;quot;, myApplicationInstance.myFunction1());

jqUnit.assertFalse(&amp;quot;My function 2 returns false&amp;quot;, myApplicationInstance.myFunction2());
jqUnit.assertTrue(&amp;quot;My variable 1 is set&amp;quot;, myApplicationInstance.myVar1);

jqUnit.assertEquals(&amp;quot;My function 3 returns correct value&amp;quot;, &amp;quot;expectedValue&amp;quot;, myApplicationInstance.myFunction3());&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The tests are pretty obvious. This takes care of the actual tests. Now we need something where we can see the results of the tests. Lets make an html file where we can include the js file that we just created. &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!--  This is the QUnit test css file --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;link&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;rel&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;stylesheet&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;screen&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lib/qunit/css/qunit.css&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!--  These are the jqUnit test js files --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text/javascript&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lib/qunit/js/qunit.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text/javascript&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;lib/test-core/jqUnit/js/jqUnit.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- The test file that you just wrote --&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;text/javascript&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;../js/myTests.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Other imports, like jQuery and your application imports --&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And finally the markup to render the tests: &lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;body&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;qunit-header&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;My Application Basic Tests&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;qunit-banner&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;qunit-testrunner-toolbar&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h2&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;qunit-userAgent&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;ol&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;qunit-tests&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;ol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;If you want to have a look at the complete test files for a live project, see my tests for the Fluid Infusion Image Editor &lt;a href=&quot;https://github.com/pulkit110/ImageEditor/tree/master/tests&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[A summer with Fluid and Google!]]></title><link>https://pulkitgoyal.in/summer-fluid-google</link><guid isPermaLink="false">https://pulkitgoyal.in/summer-fluid-google</guid><pubDate>Sun, 06 Nov 2011 00:53:42 GMT</pubDate><content:encoded>&lt;p&gt;With the end of Google Summer of Code 2011, I finished my summer with a great experience. I got the opportunity to interact with some of the best developers in the field of open source and got to learn a lot about web development, open source software and project management as I finished developing a new component, Image Editor for the fluid framework. One of the most important things that I learned while working with them was the importance of building tests. To explain more about it, I would be writing a blog post soon about jqunit soon. You can have a look at an online demo for the component &lt;a href=&quot;https://pulkitgoyal.in/imageEditor&quot; title=&quot;Image Editor Demo&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Looks cool? Integrating it into your own webpage is really easy. Checkout the &lt;a href=&quot;https://wiki.fluidproject.org/display/fluid/Tutorial+-+Image+Editor&quot; title=&quot;Image Editor Tutorial&quot; target=&quot;_blank&quot;&gt;tutorial&lt;/a&gt; and &lt;a href=&quot;https://wiki.fluidproject.org/display/fluid/Image+Editor+API&quot; title=&quot;Image Editor API&quot; target=&quot;_blank&quot;&gt;docs&lt;/a&gt;. With the Image Editor component you get two more components, the TaggerUI and CropperUI. But nothing stops you from exploring more about these separately. In fact, these components come prepared to be used individually for your website. For more details about all the component tutorials and API docs related to &lt;a href=&quot;https://wiki.fluidproject.org/display/fluid/Image+Editor&quot; title=&quot;Image Editor&quot; target=&quot;_blank&quot;&gt;Image Editor&lt;/a&gt;, &lt;a href=&quot;https://wiki.fluidproject.org/display/fluid/Tagger+UI+API&quot; title=&quot;TaggerUI API&quot; target=&quot;_blank&quot;&gt;Tagger &lt;/a&gt;and &lt;a href=&quot;https://wiki.fluidproject.org/display/fluid/Cropper+UI+API&quot; title=&quot;Cropper UI API&quot; target=&quot;_blank&quot;&gt;Cropper&lt;/a&gt;, visit the fluid wiki. For the web developers out there, have a look at the code of the components on &lt;a href=&quot;https://github.com/pulkit110&quot; title=&quot;Pulkit&apos;s Github&quot; target=&quot;_blank&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In addition to the components that I created, the fluid community has a lot to offer. I enjoyed working with them and now enjoy using the fluid components. For a detailed demo of all the fluid components, visit the &lt;a href=&quot;https://www.fluidproject.org/products/infusion/infusion-demos/&quot; title=&quot;Fluid Demonstration Portal&quot; target=&quot;_blank&quot;&gt;fluid demonstration portal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Overall, it was one of the best summers that I could have had. I hope to work with Fluid and Google again.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to update Android SDK to 4.0]]></title><link>https://pulkitgoyal.in/update-android-sdk-4-0</link><guid isPermaLink="false">https://pulkitgoyal.in/update-android-sdk-4-0</guid><pubDate>Sat, 29 Oct 2011 12:33:26 GMT</pubDate><content:encoded>&lt;p&gt;Google has recently launched android 4.0 and it is no doubt one of the best updates so far. For more details about Android 4.0, see &lt;a href=&quot;https://developer.android.com/sdk/android-4.0-highlights.html&quot; title=&quot;Android 4.0&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. To update your android sdk to version 4.0 on Windows, browse to your android installation directory (C:/Program Files (x86)/Android by default on 64bit Windows). Start SDK Manager.exe as an administrator (from the right click menu). It should then automatically search for updates and ask you for installation. Begin the installation. So far so good.
Now, something strange happens: “the latest update failed to install because it couldn’t rename the tools folder in android-sdk-windows”. You might give it a try by trying to restart the update after quitting windows explorer and disabling your antivirus software for a while. But it didn’t work for me and might not work for you as well. The problem here was that the SDK Manager itself was using the directory and therefore wasn’t able to delete it and replace it with a new one. Here’s a work around for the problem that worked for me:
Solution:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Make a copy of the tools folder itself (keeping it at the same directory tree level, thus &quot;tools&quot; and &quot;tools-copy&quot; were both in the &quot;android-sdk-windows&quot; folder).&lt;/li&gt;
	&lt;li&gt;Run Android.bat from that copy (I recommend running it as an administrator)&lt;/li&gt;
	&lt;li&gt;Re-run the update (it should now update the original, not-being-used-at-the-moment tools folder, among whatever other items it needed to).&lt;/li&gt;
	&lt;li&gt;Close the SDK, delete the folder that you built in first step (Optional) (You might need to kill the adb.exe process first - not sure why that always persists but you can&apos;t delete the folder without doing that).&lt;/li&gt;
	&lt;li&gt;Restart the SDK from the normal (now-updated) tools folder.  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now you can work with the updated sdk just like you did with the old one. For a good tutorial on how to start developing apps, visit &lt;a href=&quot;https://sapandiwakar.wordpress.com/2011/09/09/tutorial-beginners-guide-getting-started-with-development-of-basic-android-application-using-eclipse/&quot; title=&quot;Android Application development&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You might also run into a problem when you now run eclipse for developing android applications. The error that I received was this:&lt;/p&gt;
&lt;blockquote&gt;This Android SDK requires Android Developer Toolkit version 14.0.0 or above. Current version is 12.0.0.v201106281929-138431. Please update ADT to the latest version.
&lt;/blockquote&gt;
&lt;p&gt;To solve this problem:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Go to Help → Install New Software.&lt;/li&gt;
	&lt;li&gt;On Work with: type https://dl-ssl.google.com/android/eclipse/ and press ENTER.&lt;/li&gt;
	&lt;li&gt;Wait for Eclipse to fetch the repository. An item named Developer tools will appear in the list. Mark it for install, press Next and follow the steps to install the ADT tools.&lt;/li&gt;
	&lt;li&gt;When finished, it will ask to restart Eclipse. Make sure you do this.&lt;/li&gt;
	&lt;li&gt;When Eclipse restarts, all your Android SDK packages should show up again.&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title><![CDATA[[How to]Integrating Maven with Eclipse]]></title><link>https://pulkitgoyal.in/how-tointegrating-maven-with-eclipse</link><guid isPermaLink="false">https://pulkitgoyal.in/how-tointegrating-maven-with-eclipse</guid><pubDate>Mon, 17 Oct 2011 01:26:39 GMT</pubDate><content:encoded>&lt;p align=&apos;justify&apos;&gt;If you are coming to this post this means you know enough about Eclispe and Maven. For those who don&apos;t know about Maven, (from &lt;a href=&quot;https://maven.apache.org&quot;&gt;maven.apache.org&lt;/a&gt;) &lt;em&gt;Maven, a Yiddish word meaning accumulator of knowledge, was originally started as an attempt to simplify the build processes.&lt;/em&gt;
&lt;p align=&apos;justify&apos;&gt;Now a days most of the projects build through Maven. I use Maven2Eclispe (&lt;a href=&quot;https://www.eclipse.org/m2e/&quot;&gt;m2e&lt;/a&gt;) plug-in for using maven with Eclispe. To add this to your Eclipse follow these simple steps-
&lt;ol&gt;
&lt;li&gt;Go to Help(in Eclispe) click on &lt;em&gt;Install New Software&lt;/em&gt;. Add this link &lt;strong&gt;&lt;a href=&quot;https://m2eclipse.sonatype.org/sites/m2e&quot;&gt;https://m2eclipse.sonatype.org/sites/m2e&lt;/a&gt;&lt;/strong&gt; in work with option. Tick &lt;strong&gt;Maven Integration for Eclipse&lt;/strong&gt; from the check-box given below.&lt;/li&gt;
&lt;li&gt;Don’t forget to tick the &lt;em&gt;Contact all update sites during install to find required software&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Click &lt;em&gt;finish&lt;/em&gt; to complete the installation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You might get an error saying&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Cannot complete the install because one or more required items could not be found. Software being installed: Maven Integration for Eclipse (Required) 0.12.0.20101115-1102 (org.maven.ide.eclipse.feature.feature.group 0.12.0.20101115-1102) Missing requirement: Maven Integration for Eclipse (Required) 0.12.0.20101115-1102 (org.maven.ide.eclipse.feature.feature.group 0.12.0.20101115-1102) requires ‘org.eclipse.emf.ecore.edit 0.0.0’ but it could not be found.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is due to it requires &lt;em&gt;Eclispe Modelling Framework (EMF)&lt;/em&gt; for its installation but ir comes from different update site than M2Eclispe and therefore you need to add EMF framework too. To do so add &lt;em&gt;&lt;a href=&quot;https://download.eclipse.org/releases/helios&quot;&gt;download.eclipse.org/releases/helios&lt;/a&gt;&lt;/em&gt; site also and tick EMF for installation, click finish and you are DONE with it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Using Twitter4j with SSL connection]]></title><link>https://pulkitgoyal.in/using-twitter4j-with-ssl-connection</link><guid isPermaLink="false">https://pulkitgoyal.in/using-twitter4j-with-ssl-connection</guid><pubDate>Sat, 01 Oct 2011 14:29:12 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;This morning my &lt;a title=&quot;Twitter Data Collection&quot; href=&quot;https://github.com/pulkit110/Twitter-Data-Miner&quot; target=&quot;_blank&quot;&gt;Twitter Data Collection project&lt;/a&gt; suddenly stopped working. Suddenly, it failed to connect to the Twitter servers. It is as a result of the recent &lt;a href=&quot;https://dev.twitter.com/blog/streaming-api-turning-ssl-only-september-29th&quot; target=&quot;_blank&quot;&gt;announcement&lt;/a&gt; made by twitter that it would allow only SSL connections starting from 29.09.2011.&lt;/p&gt;
&lt;p&gt;I had been using twitter4j to connect to twitter stream. Even after setting the twitter4j.http.useSSL property to true, it failed to connect.The apparent solution to this was to update the twitter4j API to version 2.2.5-SNAPSHOT as announced through this &lt;a href=&quot;https://twitter.com/#!/t4j_news/status/119560883344130048&quot; target=&quot;_blank&quot;&gt;tweet&lt;/a&gt; by twitter4j. But even after updating my project’s pom.xml to the new version, the problem wasn’t resolved. I figured out that the SNAPSHOT version wasn’t getting downloaded for twitter4j-core. Here’s how I fixed the problem:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;xml&quot;&gt;&lt;pre class=&quot;language-xml&quot;&gt;&lt;code class=&quot;language-xml&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;repository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;twitter4j.org&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;id&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;twitter4j.org Repository&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;name&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;https://twitter4j.org/maven2&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;url&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;releases&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;false&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;releases&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;snapshots&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
		&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;true&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;enabled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
	&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;snapshots&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;repository&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This fixed the problem. Finally my data collection is back on track! :)&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Firefox Takeout: Take your Firefox data with you]]></title><link>https://pulkitgoyal.in/firefox-takeout</link><guid isPermaLink="false">https://pulkitgoyal.in/firefox-takeout</guid><pubDate>Wed, 07 Sep 2011 10:13:53 GMT</pubDate><content:encoded>&lt;p&gt;This post comes after a long time as I was busy in traveling. This summer I was working as Google Summer of Code Student’s for Fluid. After completing it successfully, when I was leaving the PC at my office on which I was working for my project I realized that I will lose track of all the technologies, sites and blogs etc. I had &lt;strong&gt;bookmarked &lt;/strong&gt; as well as my browsing history, which Firefox uses to show suggestion while user types something in address bar. On googling a bit about this, I found out a solution for this. But there wasn’t any software available to assist me with the process. So I decided to build one for me so that I wouldn’t have to search again whenever I move my system. I then decided to build a software by which I would be able to see all suggestions from previous system as well as suggestions which was already present in the second system, and named it &lt;strong&gt;Firefox Takeout&lt;/strong&gt; which can be found at here. This software works only on those Windows system on which English as Language is installed.&lt;/p&gt;
&lt;p&gt;So, what does the software actually do? This software works in 2 steps. First screen provides user to choose from 2 options as shown-
&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/09/firefoxtakeout.png&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_246,w_300/v1392235525/firefoxtakeout_der9in.png&quot; alt=&quot;Firefox Takeout&quot; title=&quot;firefoxtakeout&quot; width=&quot;300&quot; height=&quot;246&quot; class=&quot;size-medium wp-image-358&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align=&apos;justify&apos;&gt;When user chooses 1st option that is &lt;strong&gt;Takeout Firefox data&lt;/strong&gt; from first system; file used by Firefox for showing suggestion to the user while typing, is copied inside &lt;em&gt;Firefox Transform&lt;/em&gt; folder located on desktop (It creates the folder if it doesn&apos;t exist). This completes 1st step. Now user can copy this folder and paste it on desktop of 2nd system. This is pre-requisite for the 2nd step. Now on the 2nd system, user can select 2nd option, i.e.,  &lt;strong&gt;Bring in Firefox data&lt;/strong&gt;, this will send the file to the destination. &lt;/p&gt;
&lt;p align=&apos;justify&apos;&gt;This software was not difficult to build but it simplifies the life of the user to a great extent when user switches from one system to another specially to those uses which uses bookmarks and are not able to keep track of site visited by them. I think you will enjoy using this software. I will be improving the software&apos;s functions, look and feel in the future. Feel free to follow the development on the &lt;a href=&quot;https://sourceforge.net/p/firefoxtakeout/home/Home/&quot; target=&quot;_blank&quot;&gt;project page at sourceforge&lt;/a&gt;. If you face any problems, I would be glad to help. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Javascript Image Manipulation using HTML5 canvas element [Tutorial]]]></title><link>https://pulkitgoyal.in/javascript-image-manipulation-using-html5-canvas-element-tutorial</link><guid isPermaLink="false">https://pulkitgoyal.in/javascript-image-manipulation-using-html5-canvas-element-tutorial</guid><pubDate>Sun, 12 Jun 2011 23:20:04 GMT</pubDate><content:encoded>&lt;p&gt;I have been working with &lt;code class=&quot;language-text&quot;&gt;HTML5&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Javascript&lt;/code&gt; for my Google summer of code project for the Fluid Project. This post is the first of a series of tutorials which I would be posting related to Javascript, HTML5 (especially canvas element) and Fluid Infusion.&lt;/p&gt;
&lt;p&gt;I have been exploring ways to get image pixels from an image object using Javascript. As far as I know, the only way of doing this so far is by using the HTML5 canvas element. So, you can either build a canvas element yourself and get the pixels or use some nice Image Processing library such as &lt;a title=&quot;Pixastic&quot; href=&quot;https://www.pixastic.com/&quot; target=&quot;_blank&quot;&gt;Pixastic&lt;/a&gt;. I would now be describing more about image processing using canvas element. I assume that you know a bit about the HTML5 canvas element beforehand. For knowing more about canvas, I recommend going through these &lt;a title=&quot;HTML5 Canvas Tutorial &quot; href=&quot;https://developer.mozilla.org/en/canvas_tutorial&quot; target=&quot;_blank&quot;&gt;tutorials by Mozilla&lt;/a&gt;. I also assume that you have got an Image object for which you want to manipulate pixels.&lt;/p&gt;
&lt;p&gt;Top obtain the pixels for a given image, you first have to draw that image on canvas and then get the pixels using the &lt;code class=&quot;language-text&quot;&gt;getImageData&lt;/code&gt; method on canvas context.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; imageManipulationCanvas &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; imageManipulationCtx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;2d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCtx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drawImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Draw image on temporary canvas&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; myImageData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; imageManipulationCtx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getImageData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Parameters are left, top, width and height&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The image data object has three fields: &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;data&lt;/code&gt; where data is the &lt;code class=&quot;language-text&quot;&gt;CanvasPixelArray&lt;/code&gt; object which contains pixel data for image.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;CanvasPixelArray&lt;/code&gt; object can be accessed to look at the raw pixel data; each pixel is represented by four one-byte values (red, green, blue, and alpha, in that order; that is, “RGBA” format). Each color component is represented by an integer between 0 and 255. Each component is assigned a consecutive index within the array, with the top left pixel’s red component being at index 0 within the array. Pixels then proceed from left to right, then downward, throughout the array.&lt;/p&gt;
&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;CanvasPixelArray&lt;/code&gt; contains &lt;code class=&quot;language-text&quot;&gt;height x width x 4&lt;/code&gt; bytes of data, with index values ranging from &lt;code class=&quot;language-text&quot;&gt;0 to (height x width x 4)-1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Now you can manipulate the pixels as you want for any image. However for simple operations like resizing and cropping, I prefer using different variations of the drawImage function rather than manipulating the pixels myself. Here’s how to resize an image using drawImage:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; imageManipulationCanvas &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newW&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newH&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; imageManipulationCtx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;2d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCtx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drawImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;that&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resizeW&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; resizeH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Draw resized image on temporary canvas&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; resizedImageDataURL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toDataURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//get DataURL for cropped image&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; resizedImageDataURL&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//DataURL can be directly used to make new image pbject by using image.src&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And, the following for cropping an image:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; imageManipulationCanvas &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;canvas&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newH&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; newW&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; imageManipulationCtx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getContext&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;2d&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;//use drawImage(Object image, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh)&lt;/span&gt;
imageManipulationCtx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;drawImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; croppingDimensionX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; croppingDimensionY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; croppingDimensionW&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; croppingDimensionH&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; croppingDimensionW&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; croppingDimensionH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// Draw cropped image on temporary canvas&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; croppedImageDataURL &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; imageManipulationCanvas&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;toDataURL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;//get DataURL for cropped image&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; croppedImageDataURL&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Tutorial 4: Building the Yellow Pages Application]]></title><link>https://pulkitgoyal.in/tutorial-4-building-the-yellow-pages-application</link><guid isPermaLink="false">https://pulkitgoyal.in/tutorial-4-building-the-yellow-pages-application</guid><pubDate>Sun, 05 Jun 2011 21:51:41 GMT</pubDate><content:encoded>&lt;p&gt;Go through &lt;a href=&quot;/tutorial-3-creating-forms-supporting-multiple-languages/&quot; title=&quot;Tutorial 3: Creating Forms &amp;amp; Supporting Multiple Languages&quot;&gt;Tutorial 3&lt;/a&gt;&lt;/a&gt; first.&lt;/p&gt;
&lt;p&gt;In this tutorial, we would build a Yellow Pages Application. We will continue it from the last tutorial and extend it to have one more form and another dialog, the MessageQueryDialog to display the required data. We will also look into Symbian File Handling to retrieve the data about businesses.&lt;/p&gt;
&lt;p&gt;First, add another form in the resource file in a similar fashion as the earlier form(define a resource in resource file and class to handle the form events) to provide for selection of category. Go through the previous tutorial if you have any problems in adding another form. Once the form is added, we need to execute the form after the city is successfuly selected in the first form. To do this, we make a new form object in the SaveFormDataL() method of the first form(just like we did in HandleCommand for the first form). Once, we have extracted the city and categories, we will now extract the corresponding information about the businesses in the city for the category from te file that we have stored in the phone’s memory.(You need to make those files(or copy them from the YPages folder) and place them in the memory) For running the application on the emulator, just place the folder YPages from the current directory to the SDK’s winscw folder-&lt;/p&gt;
&lt;p&gt;Default Path: &lt;code class=&quot;language-text&quot;&gt;C:S60devicesS60_5th_Edition_SDK_v1.0epoc32winscwd&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;File Handling in Symbian:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;First, you need to obtain a handle to File Server session and connect to it. You can do this by:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RFs fileServer;
User :: LeaveIfError (fileServer.Connect());&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, we will use the RFile class to read data. Open the file for reading. The EFileStreamText flag denotes that the file opened is a text file. The EOF is indicated by the return value of TTextFile::Read(), which is KErrEof.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;RFile file;
User::LeaveIfError(file.Open(fileServer, KMyTextFile, EFileRead|EFileStreamText));&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The class to read a text file is TFileText. It is declared in &lt;em&gt;f32file.h &lt;/em&gt;header file and a library named efsrv.lib(add this to the mmp file). Before using TFileText, we have to open a file using RFile because &lt;em&gt;TFileText&lt;/em&gt; does not have an Open method. &lt;em&gt;TTextFile&lt;/em&gt; has Read() method which requires a 16 bit descriptor parameter because Symbian OS stores text files in unicode format. Do not use TFileText to open a file other than unicode. we will get garbage characters if trying to access non Unicode files, such as ASCII files. Go through the source code to understand clearly.&lt;/p&gt;
&lt;p&gt;Close the file server session after the reading is completed.&lt;/p&gt;
&lt;p&gt;After successfuly reading data from the file, we will now print the read data in a MessageQueryDialog. We must first define the resoruce for this dialog. We have defined a r&lt;em&gt;about&lt;/em&gt;heading_pane resource in the resource file. It is similar to previous dialogs, define the flags, cba function, and items. the difference here is that we do not define a for for this dialog. Instead we define 2 items, heading pane, and a CAknMessageQuery to hold the text.&lt;/p&gt;
&lt;p&gt;After defining the resource in the resource file, we must execute the resource in the SaveFormDataL() after reading the data from file. For this, create a new object of type CAknMessageQueryDialog and Prepare it with the resource defined in the resource file. Then, set the header text and finally call RunLD() on dialog to display it. The text to be displayed in the dialog was passed alongwith the dialog’s constructor while making the new object.&lt;/p&gt;
&lt;p&gt;Download Source code for this tutorial &lt;a href=&quot;https://wl37www31.webland.chdiwakar.webs.com/Symbian/YPages1.rar&quot; title=&quot;Tutorial: 4&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Tutorial 3: Creating Forms & Supporting Multiple Languages]]></title><link>https://pulkitgoyal.in/tutorial-3-creating-forms-supporting-multiple-languages</link><guid isPermaLink="false">https://pulkitgoyal.in/tutorial-3-creating-forms-supporting-multiple-languages</guid><pubDate>Sun, 05 Jun 2011 21:28:24 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Go through &lt;a href=&quot;/tutorial-2-first-dialog/&quot; title=&quot;Tutorial 2 : First Dialog&quot;&gt;tutorial 2&lt;/a&gt; first.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;In this tutorial, we look into more complex dialogs. For our application, we use the form dialog. A form displays a set of data fields in the form of a list, with each data field in the list consisting of a label and a control. The label can be on the same line as the control, or it can be on a separate line, with the control below it. In addition, a form dialog is automatically associated with a standard menu that supplies the options:&lt;br&gt;
  Add field, Edit label, Delete field, Save and, optionally, Edit.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;Selecting one of the first four of these options results in a call to the appropriate one of the CAknForm functions: &lt;em&gt;AddItemL()&lt;/em&gt;, &lt;em&gt;EditCurrentLabel()&lt;/em&gt;, &lt;em&gt;DeleteCurrentItem()&lt;/em&gt; and &lt;em&gt;SaveFormDataL()&lt;/em&gt;. In our application, we use only the save option which in turn calls the SaveFormDataL() function.&lt;br&gt;
  An S60 form has two modes: in &apos;view&apos; mode it acts as an application view that displays a list of data items, and in &apos;edit&apos; mode it can be used to modify the data items displayed. By default, it starts up in &apos;view&apos; mode and you can switch to &apos;edit&apos; mode by selecting the Edit menu option. When you have finished editing the data, you press the right softkey (temporarily labeled Done)to return to the &apos;view&apos; mode. A form is actually more powerful than a dialog. If, for example, the data items it is displaying are the fields of a database record, you can implement the commands described above to add, delete, or modify entire records.&lt;br&gt;
  You can specify that the form should be edit-only (via a fiag in the FORM resource), so that the form is always in &apos;edit&apos; mode, and in this case, the Edit menu option does not appear.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;You can also override its DynInitMenuPaneL() to disable some or all of the other menu options. You specify a form in the resource file by creating a FORM resource and assigning it to the form attribute of a DIALOG resource (or a PAGE resource for multipage dialogs). The FORM resource contains the list of DLG LINES that specify the label and control for each field in the form&apos;s list.&lt;/p&gt;
&lt;p&gt;We can also provide support for multiple languages in the application through the rls file. While you can put text strings directly within the resource file, this is not recommended if you need your application to support different languages. Symbian recommends that you put all your strings into a RLS file, and then include this string file using &lt;em&gt;#include&lt;/em&gt;in your RSS file. There should be a separate RLS file for each language you support.&lt;br&gt;
Each string in the RLS file is defined using the rls string keyword. For example:
&lt;code class=&quot;language-text&quot;&gt;rls_string STRING_r_gui_start &amp;amp;quot;Start&amp;amp;quot;;&lt;/code&gt;&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;As you can see, the DIALOG resource defines the flags and softkeys, and the form attribute points to a FORM resource. This resource specifies the dialog&apos;s content which, in this case, consists of one dialog line: a S60-specific control, known as a pop-up field (type EAknCtPopupFieldText and control structure POPUP FIELD), which is used to select the city. The FORM resource has an additional flags attribute, which is used here to set each control and its prompt to be displayed on separate lines, and to set the &apos;edit only&apos; mode that was mentioned earlier. We also define the list of cities to appear in the popup field using a RESOURCE ARRAY r_city_list.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;PreLayoutDynInit() is overridden to set the initial values of the controls in the form. We also override the SaveFormDataL() method to perform the save operations. For our application, we obtain the index of the selected city from the popup menu using the CurrentValueIndex() method in popupFieldText. we then print a dialog similar to the one printed in the second app to display the selected city index. The descriptor method Format() does this. The format string supplied to Format() is very similar to the format string in C, supporting %d, %s, %f, etc.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;This wont display the form on the screen. To make the form appear on the screen once we select the start menu item, we need to handle the command in HandleCommand() method in Application Ui Class. We create a new form object and execute R_THIRDAPP_DIALOG which was defined in the resource file.&lt;/p&gt;
Download Source code for this tutorial &lt;a href=&quot;https://wl37www31.webland.chdiwakar.webs.com/Symbian/ThirdApp.rar&quot; title=&quot;Tutorial: 3&quot;&gt;here&lt;/a&gt;.
Go through &lt;a href=&quot;/tutorial-4-building-the-yellow-pages-application/&quot; title=&quot;Tutorial 4: Building the Yellow Pages Application&quot;&gt;tutorial 4&lt;/a&gt; now.</content:encoded></item><item><title><![CDATA[Tutorial 2 : First Dialog]]></title><link>https://pulkitgoyal.in/tutorial-2-first-dialog</link><guid isPermaLink="false">https://pulkitgoyal.in/tutorial-2-first-dialog</guid><pubDate>Sun, 05 Jun 2011 21:14:45 GMT</pubDate><content:encoded>&lt;p&gt;Go through &lt;a href=&quot;/tutorial-1-learning-the-basics/&quot; title=&quot;Tutorial 1 : Learning the basics&quot;&gt;tutorial 1&lt;/a&gt; first.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;Now that you know how to print text on the screen, lets go to a little more complex application. We aregoing to add a menu to the application, how to handle commands in a little more detail, and finally create an alert dialog.&lt;/p&gt;
&lt;p&gt;Here are the changes that it makes to the first tutorial. &lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Add the menu bar resource in the resource file to display the menu. The menubar attribute of EIK APP INFO is assigned a resource of type MENU BAR, which specifies the application&amp;rsquo;s default menu. Menu bar resources have one or more menu titles (type MENU TITLE)and each menu title points to a menu pane (type MENU PANE). The menu bar in the example, r_SecondApp_menubar, has a single menu title and this points to menu pane r_SecondApp_menu. Menu panes define the actual menu items (type MENU ITEM), whichthe user selects to invoke some operation in the application. r_SecondApp_menu defines a menu item labeled &amp;lsquo;Start&amp;rsquo; that sends the command ESecondAppCommand to the GUI command handler code when the user selects it (so the code can display the Application&amp;rsquo;s dialog). &lt;/li&gt;
  &lt;li&gt;Now, we need to define the command codes used in the resource file. These are defined in the &lt;em&gt;.hrh&lt;/em&gt; file. The file SecondApp.hrh contains the command values that the controls send (specified in the resource file) for the application code to handle. In this case we have only one, used when Start is selected:
    ```
    enum TSecondAppIds {
      ESecondAppCommand = 1
    };
    ```
&lt;/li&gt;
 &lt;li&gt;the menu item &amp;lsquo;Start&amp;rsquo; is selected, the GUI framework invokes the HandleCommandL() method, passing it the command ESecondAppCommand (the command specified in the menu resource in the SecondApp.rss file). HandleCommandL() responds to this command by popping up an alert window with the message &amp;lsquo;Your First Dialog!&amp;rsquo;.We can use the iEikonEnv-&amp;gt;AlertWin() function for the pop-up since this is a core GUI method available to all platforms. This function takes one arguement which is a descriptor.
    &lt;ul&gt;
      &lt;li&gt; &lt;p align=&quot;justify&quot;&gt; Descriptors are classes that represent data buffers and allow you to safely access them. Symbian OS uses descriptors to store and manipulate strings (as opposed to NULL-terminated C strings), as well as to manage binary data. Descriptor classes, although containing many features, are optimized for minimal overhead, since they are designed to run on memory-constrained devices. There are multiple descriptor classes available in Symbian. You&amp;rsquo;ll need to use descriptors to call many of the Symbian OS API functions.&lt;/p&gt;&lt;/li&gt;
      &lt;li&gt;A String Literal(Descriptor) in Symbian is declared as:&lt;br&gt;
[cpp]        _LIT(KMessage,&amp;quot;My First Dialog!&amp;quot;);[/cpp]&lt;br&gt;
        The LIT macro is called to take the string &quot;My First Dialog!&quot;                   and stores both the string and the string&amp;rsquo;s size in the                   descriptor literal KMessage.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;
Download Source code for this tutorial &lt;a href=&quot;https://wl37www31.webland.chdiwakar.webs.com/Symbian/SecondApp.rar&quot; title=&quot;Tutorial: 2&quot;&gt;here&lt;/a&gt;.
Go through &lt;a href=&quot;/tutorial-3-creating-forms-supporting-multiple-languages/&quot; title=&quot;Tutorial 3: Creating Forms &amp;amp; Supporting Multiple Languages&quot;&gt;tutorial 3&lt;/a&gt; now.</content:encoded></item><item><title><![CDATA[Tutorial 1 : Learning the basics]]></title><link>https://pulkitgoyal.in/tutorial-1-learning-the-basics</link><guid isPermaLink="false">https://pulkitgoyal.in/tutorial-1-learning-the-basics</guid><pubDate>Sun, 05 Jun 2011 20:53:11 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Now that you have downloaded the SDK and know how to make projects in Carbide, we will now look into our first GUI Application which prints a line of text in the center of the screen. The main goal of this tutorial is to get a feel for developing a basic application by actually building and running one on the emulator.&lt;/p&gt;
&lt;h3&gt;Application Architecture&lt;/h3&gt;
&lt;p&gt;A minimal Symbian GUI Application must contain the following 4 classes:&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt; &lt;strong&gt;Application View:&lt;/strong&gt; The view class implements the application&amp;apos;s screen display, including drawing the window and the creation of the initial screen controls. The class is inherited from CCoeControl which is fine for Applications with just one view class. We would only be discussing a single view class for now.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application UI:&lt;/strong&gt; This class instantiates the application view and handles the commands sent from the application&amp;apos;s GUI controls.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application document:&lt;/strong&gt; This class handles the non-GUI data aspects of the application &amp;#x2013; the application data. It also instantiates the application&amp;apos;s UI class.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application:&lt;/strong&gt; This class is used to identify the application (by returning the application&amp;apos;s UID) and to instantiate, and return a pointer to, your application&amp;apos;s document class.&lt;/p&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/classes.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_187,w_300/v1392235532/classes_s8m9ri.jpg&quot; alt title=&quot;classes&quot; width=&quot;550&quot; height=&quot;350&quot; class=&quot;aligncenter size-medium wp-image-270&quot;&gt;&lt;/a&gt;
&lt;p&gt;Now let us discuss these classes one by one.&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;Application View Class:&lt;/strong&gt;&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt; The application view class handles the presentation of your application on the smartphone&apos;s screen, as well as allowing the user to interact with your program. In Symbian OS all objects drawn to a screen are controls – including the application view, which is a custom control. It has the following methods:&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt; NewL, NewLC and ConstructL: These methods construct a new object of the view class. We will discuss about why we took these 3 methods and not just the constructor to construct the new object later in error handling.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt; Draw(): Draw() is a method called by the framework for every control in order to draw it to the screen. The application view is a control, and, we implement the Draw() function to output the text &apos;First Application&apos; in the center of the window. The drawing is performed by opening a graphics context (GC), getting a font, and calling the context&apos;s DrawText() function. Cleanup is performed on the font upon&lt;/p&gt;
  completion.(Cleanup will be explained in error handling.)&lt;/p&gt;
&lt;strong&gt;&lt;p&gt; Application UI Class:&lt;/p&gt;&lt;/strong&gt;
&lt;p align=&quot;justify&quot;&gt; Your application&apos;s UI class is responsible, upon construction, for creating the application&apos;s default view. In S60, for basic one-view applications (i.e., the view is a simple control), the UI class contains the command handler that handles all the commands the users initiate via the GUI. If you are using multiple views, however, this command handler would be in the view class. It has the following methods:&lt;/p&gt;
  ConstructL(): This function does the work of construction of an object of View Class.&lt;br&gt;
  HandleCommandL(): This function handles the commands passed from the Application&apos;s GUI controls. In this application, we just need to handle the commands for exiting the application.&lt;/p&gt;
&lt;strong&gt;&lt;p&gt; Application Document Class:&lt;/p&gt;&lt;/strong&gt;
&lt;p align=&quot;justify&quot;&gt; The document class has two purposes, the first of which is to represent the application&apos;s persistent data(Data that needs to remain after application is exited). The other is to create the application UI instance in which this data (if any) can be manipulated. For applications that have no persistent data, and therefore are not file-based, the document class simply implements the CreateAppUiL() function to return the application&apos;s UI object.&lt;/p&gt;
&lt;strong&gt;&lt;p&gt; Application Class:&lt;/p&gt;&lt;/strong&gt;
&lt;p&gt; This is the first thing the GUI framework creates. It has the following methods:&lt;br&gt;
  CreateDocumentL(): This function creates an object of Document class and returns a pointer to it.&lt;br&gt;
  AppDllUid(): This function returns the Application&apos;s Uid.&lt;/p&gt;
&lt;strong&gt;&lt;p&gt;E32Main()Entrypoint and NewApplication()&lt;/p&gt;&lt;/strong&gt;
&lt;p align=&quot;justify&quot;&gt; A Symbian OS GUI application is a process executable (EXE file) and therefore must contain an E32Main() entrypoint function. For a GUI application this just calls EikStart::RunApplication(), passing it a pointer to a function that returns the application object to run.&lt;/p&gt;
&lt;strong&gt;&lt;p&gt;Resource Files:&lt;/p&gt;&lt;/strong&gt;
&lt;p align=&quot;justify&quot;&gt;The application resource defines a significant part of how the application will appear and function. The resource file is a text file whose name ends in .rss, and is compiled into a binary form by the SDK&apos;s resource compiler. This compiled version of the resource file is loaded onto the phone along with the application executable and is accessed during application execution.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt; The RSS_SIGNATURE resource is used to validate the file and must appear, exactly as shown below, as the first resource in every appliation&apos;s resource file.&lt;/p&gt;
&lt;p&gt; [cpp] RESOURCE RSS_SIGNATURE
  {
  }[/cpp]&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt; TBUF Resource defines the default document name. As a document is not used in the application, it is left blank.&lt;br&gt;
  The EIK_APP_INFO Resource defines a Control Button Array(cba) resource that defines the function of the left and right softkeys. We define the cba as &amp;quot;R_AVKON_SOFTKEYS_EXIT&amp;quot;. This defines the right softkey as exit and generates the command &amp;quot;EAknSoftkeyBack&amp;quot; when activated which is in turn handled by the Application UI class.&lt;/p&gt;
&lt;strong&gt;&lt;p&gt;Application Registration Resource File:&lt;/p&gt;&lt;/strong&gt;
&lt;p align=&quot;justify&quot;&gt; GUI applications are EXE files in the sysbin directory and in order for the device to recognize an executable as a GUI application, and to display them on the desktop for user selection, the application must be registered via a special resource file known as a&lt;br&gt;
  registration resource file. The source file names are typically &amp;lt;application name&amp;gt; reg.rss. Walkthrough the reg_rss file for more details.&lt;/p&gt;
&lt;strong&gt;&lt;p&gt;Project Build Files:&lt;/p&gt;&lt;/strong&gt;
&lt;p&gt; These are the files that define how to build a project:&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;FirstApp.mmp:&lt;/strong&gt; It defines what source and resource files should be compiled and what libraries should be used for linking. The locations to search for project-defined and system include files, and source files and locations, are also defined&lt;br&gt;
&lt;p&gt;&lt;strong&gt;bld.inf:&lt;/strong&gt; The file bld.inf points the build tools to the correct project definition&lt;br&gt;
(MMP) file.&lt;/p&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
Download Source code for this tutorial &lt;a href=&quot;https://wl37www31.webland.chdiwakar.webs.com/Symbian/FirstApp.rar&quot; title=&quot;Tutorial: 1&quot;&gt;here&lt;/a&gt;.
Go to &lt;a href=&quot;https://pulkitgoyal.wordpress.com/2011/06/05/tutorial-2-first-dialog/&quot; title=&quot;Tutorial 2 : First Dialog&quot;&gt;tutorial 2&lt;/a&gt; now.</content:encoded></item><item><title><![CDATA[Building the Yellow Pages Application]]></title><link>https://pulkitgoyal.in/building-the-yellow-pages-application</link><guid isPermaLink="false">https://pulkitgoyal.in/building-the-yellow-pages-application</guid><pubDate>Sun, 05 Jun 2011 20:25:06 GMT</pubDate><content:encoded>&lt;p&gt; Read the following chapters of the book, Developing Software for Symbian             OS by Steve Babin.                         : &lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Chapter 1: Smartphones and Symbian OS&lt;/li&gt;
  &lt;li&gt;Chapter 2: Symbian OS Quick Start&lt;/li&gt;
  &lt;li&gt;Chapter 4: Symbian OS Programming Basics&lt;/li&gt;
  &lt;li&gt;Chapter 6: Strings, Buffers, and Data Collection (Important)&lt;/li&gt;
  &lt;li&gt;Chapter 12: GUI Application Programming&lt;/li&gt;
&lt;/ol&gt;
This would require about 8-10 days.
&lt;p align=&quot;justify&quot;&gt;In addition to this, we also referred to Nokia Forums,             NewLC and the book, &amp;quot;Quick Recipes on Symbian OS Mastering C++             Smartphone Development&amp;quot; by Michael Aubert. (Section 4.1 : File             Handling) &lt;/p&gt;
&lt;p&gt;After reading the book we started off with a top-down design  	 of the App (Use case analysis, class design, realization etc). &lt;/p&gt;
&lt;p&gt;&amp;#xA0;Application Use Case Analysis&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;User selects City from a list.&lt;/li&gt;
  &lt;li&gt;User selects Category from a list. &lt;/li&gt;
  &lt;li&gt;System presents the list of Companies and               their phone numbers to the user.&lt;/li&gt;
&lt;/ol&gt;
&lt;br&gt;
&lt;h2&gt;Application Architecture&lt;/h2&gt;
&lt;p&gt;A Symbian GUI App contains 4 classes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application View&lt;/strong&gt;: The root GUI control, this class implements the main window and acts as a container for the other application controls.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application UI&lt;/strong&gt;: This class instantiates the application               view and handles the commands sent from the application&amp;#x2019;s GUI controls.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application document&lt;/strong&gt;: This class handles the non-GUI               data aspects of the application &amp;#x2013; the application data. It also               instantiates the application&amp;#x2019;s UI class.&lt;/p&gt;&lt;/li&gt;
  &lt;li&gt;
    &lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;Application&lt;/strong&gt;: The main application                 class starts the application by instantiating and starting the document                 class. It also sets the application&amp;#x2019;s UID.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/classdiagram.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_187,w_300/v1392235539/classdiagram_pzscel.jpg&quot; alt title=&quot;classDiagram&quot; width=&quot;500&quot; height=&quot;387&quot; class=&quot;aligncenter size-medium wp-image-252&quot;&gt;&lt;/a&gt;
&lt;p align=&quot;justify&quot;&gt;The application resource defines a significant part of how the application             will appear and function. The resource file is a text file whose name             ends in .rss, and is compiled into a binary form by the SDK’s             resource compiler. This compiled version of the resource file is loaded             onto the phone along with the application executable and is accessed             during application execution. &lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;For making the GUI components, we must first define the GUI components             in the resource file. For our Yellow Pages, we first define a MenuBar.             We defined a menubar with just one item, &amp;quot;Select City&amp;quot;. It             should then display a dialog with a form to select the city-&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/city.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_300,w_213/v1392235536/city_mufac4.jpg&quot; alt title=&quot;city&quot; width=&quot;213&quot; height=&quot;300&quot; class=&quot;aligncenter size-medium wp-image-259&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p align=&quot;left&quot;&gt;Selecting a City and saving then creates another form which provides options for selecting the category- &lt;/p&gt;
&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/category.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_300,w_209/v1392235535/category_ztxqha.jpg&quot; alt title=&quot;category&quot; width=&quot;209&quot; height=&quot;300&quot; class=&quot;aligncenter size-medium wp-image-261&quot;&gt;&lt;/a&gt;
&lt;p align=&quot;justufy&quot;&gt;After that, the data is read from a file and the names             of companies and their phone numbers are dispayed in a MessageQueryDialog.&lt;/p&gt;
&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/box.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_300,w_211/v1392235533/box_j71kij.jpg&quot; alt title=&quot;box&quot; width=&quot;211&quot; height=&quot;300&quot; class=&quot;aligncenter size-medium wp-image-262&quot;&gt;&lt;/a&gt;
&lt;p align=&quot;center&quot;&gt;&amp;#xA0;&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;The UI class handles the commands from these GUI resources,             whereas the CYPagesForm &amp;amp; CYPagesForm1 handle the dialog forms defined             in the resource as follows. CYPagesForm &amp;amp; CYpagesForm1 have methods             like DynInitMenuPane which initializes the resource defined in the resource             files using the resource id, and other methods to handle the forms. &lt;/p&gt;</content:encoded></item><item><title><![CDATA[Google Summer of Code with Fluid Infusion]]></title><link>https://pulkitgoyal.in/google-summer-of-code-begins</link><guid isPermaLink="false">https://pulkitgoyal.in/google-summer-of-code-begins</guid><pubDate>Wed, 01 Jun 2011 18:26:38 GMT</pubDate><content:encoded>&lt;p&gt;People who are waiting for my Symbian tutorials would have to wait. In the past couple of weeks, I haven’t had the time to write those tutorials as I have been working on a &lt;a href=&quot;https://code.google.com/soc/&quot; target=&quot;_blank&quot;&gt;Google Summer of Code &lt;/a&gt;Project for the &lt;a href=&quot;https://idrc.ocad.ca/&quot; target=&quot;_blank&quot;&gt;Inclusive Design Institute&lt;/a&gt;. For those who are unfamiliar with Google Summer of Code, it is a program that offers student developers the opportunity to write code for various open source projects. The project that I am working on is &lt;a href=&quot;https://wiki.fluidproject.org/display/fluid/Image+Editor&quot; target=&quot;_blank&quot;&gt;Image Editor &lt;/a&gt;which will be developed as a component for the &lt;a href=&quot;https://www.fluidproject.org/products/infusion/&quot; target=&quot;_blank&quot;&gt;fluid infusion framework&lt;/a&gt;. Fluid Infusion is a Javascript library that provides several components for building awesome interfaces for the web. I will be talking about a lot of things related to GSoC in this post. Lets get started.&lt;/p&gt;
&lt;p&gt;Google announces GSoC every year sometime in January. It then accepts applications from several organizations who wish to work under the program and hire student developers for the summer. Few organizations get selected which then propose several projects on which the students would work on during the summer. This is when the students start their journey. I looked at several organizations and listed a few whose projects matched with my field of interest. The next step is to learn more about these organizations and make sure that you would like to work with them in the summer. It is very important to identify the correct organization and the correct project that you want to be working on. We can get to know more about the organizations by hanging out in their IRC channels or joining their mailing lists.&lt;/p&gt;
&lt;p&gt;After this, I started writing proposals for the projects which I was interested to work on. This is probably the most important step of the application process. This is where the organizations can know about whether you have understood about the project and how much work do you propose to do. At this step, one could get feedback about the proposal from the mentor organization as to what they expect from the proposal. There is no such thing like a set of guidelines for writing a proposal because different organizations look for different things in the proposal. But, in general, a proposal should be realistic and to the point with at least a basic timeline of the work that you expect to complete every 15 days. One can submit upto 20 proposals to Google. Again this is an upper limit and is not at all recommended. Proposals should be submitted only to organizations which really interest you. Also one should focus on the quality of proposal rather than the quantity.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;After this phase, one can either choose to relax till the declaration of results or study about the projects that he submitted proposals for. A few lucky ones make it to GSoC and it is an opportunity to get to know more about how large open source organizations work as well as contribute back to the open source community. This was just the beginning. The real work starts after being selected for GSoC. I guess, this is a long enough list of suggestions for the GSoC Applicants. I will now talk about my GSoC proposal and the wonderful organization that I have started working with.  &lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;You can find my proposal on Image Editor &lt;a href=&quot;https://docs.google.com/document/pub?id=1Z3tQ8uLFlPeL8djGdG62hr_6GJxAmD8gW3hD0wDmRHw&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. This is the final version of the proposal which I came up with after a few discussion with the mentor for Image Editor, &lt;a href=&quot;https://wiki.fluidproject.org/display/~michelled&quot; target=&quot;_blank&quot;&gt;Michelle D&apos;Souza&lt;/a&gt;. I was very excited after I came to know that I had been accepted for Goolge Summer of Code. Frankly, it came to me as a shock. Thanks again to Fluid for giving me this wonderful opportunity. &lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;During the community bonding period, I started looking up documentation on Fluid Infusion and remained in the IRC channel. This was the first time that I was working on a big open source project involving several developers. But, the Fluid community is really wonderful everyone is more than willing to help. With the help and support from my mentor as well as the developers, I was able to pickup the framework quickly and started developing simple components. I am working using github and all the code that I develop is available &lt;a href=&quot;https://github.com/pulkit110/ImageEditor&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;. I am doing the development using JavaScript, HTML5, PHP and am working on Aptana Studio. I will be talking more about developing components for fluid and how to use fluid to develop good interfaces in my next posts.  &lt;/p&gt;
&lt;p&gt;In the meantime, I also received the Welcome Package for Google Summer of Code students. I was very excited to receive the package as it was from &lt;strong&gt;Google&lt;/strong&gt;. Well, I guess that’s enough for today. I should probably get back to coding :).  Have a look at my welcome package:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/gsoc1.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_225,w_300/v1392235543/gsoc1_fznips.jpg&quot; alt title=&quot;GSOC1&quot; width=&quot;300&quot; height=&quot;225&quot; class=&quot;alignleft size-medium wp-image-219&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/06/gsoc2.jpg&quot;&gt;&lt;img src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_300,w_225/v1392235540/gsoc2_i1kejx.jpg&quot; alt title=&quot;GSOC2&quot; width=&quot;225&quot; height=&quot;300&quot; class=&quot;alignright size-medium wp-image-220&quot;&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Step by step tutorial for your first Symbian Application]]></title><link>https://pulkitgoyal.in/step-by-step-tutorial-for-your-first-symbian-application</link><guid isPermaLink="false">https://pulkitgoyal.in/step-by-step-tutorial-for-your-first-symbian-application</guid><pubDate>Tue, 24 May 2011 12:30:43 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Welcome. This post will guide you about C++ programming for the Series 60 v5  platform, based on the Symbian Operating System. I wrote these tutorial along with my colleague &lt;a href=&quot;https://sapandiwakar.in&quot; title=&quot;Sapan&quot;&gt;Sapan&lt;/a&gt;, when we were doing summer internship at IIIT- Hyderabad. We built a simple application named &lt;em&gt;&quot;Yellow Page Application&quot; &lt;/em&gt;under guidance of Dr. Rohit Agarwal. The term Yellow Pages refers to a telephone directory of businesses, categorized according to the product or service provided. This application does the work of displaying this information to the user on the go using just his mobile phone. In this way, he can get the information about the business he is looking for in a particular city.This application lists major businesses (Banks, Clinics and Doctors etc.) in 4 major cities of India.
&lt;p align=&quot;justify&quot;&gt;We have divided this tutorial in 5 parts which will guide you How to build a basic &lt;em&gt;Symbian application from scratch&lt;/em&gt;. Before going further I suggest you to get familiarize yourself with the application first and read &lt;a href=&quot;/building-the-yellow-pages-application/&quot; title=&quot;Building the Yellow Pages Application&quot;&gt;this&lt;/a&gt;.
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;&lt;a href=&quot;/tutorial-start-page/&quot; title=&quot;Tutorial Start Page&quot;&gt;Tutorial Start Page&lt;/a&gt;&lt;/strong&gt; : This part will describe about prerequisite setup needed for building any Symbian Application.
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;&lt;a href=&quot;/tutorial-1-learning-the-basics/&quot; title=&quot;Tutorial 1 : Learning the basics&quot;&gt;Tutorial 1&lt;/a&gt;:&lt;/strong&gt; This part will tell you about 4 necessary classes that you must define in order to build Symbian Application.
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt; &lt;a href=&quot;/tutorial-2-first-dialog/&quot; title=&quot;Tutorial 2 : First Dialog&quot;&gt;Tutorial 2:&lt;/a&gt;&lt;/strong&gt; This part will show you how to build a dialog box in Symbian Operating System.
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt; &lt;a href=&quot;/tutorial-3-creating-forms-supporting-multiple-languages/&quot; title=&quot;Tutorial 3: Creating Forms &amp;amp; Supporting Multiple Languages&quot;&gt;Tutorial 3:&lt;/a&gt;&lt;/strong&gt; This part creates forms and provides support for your application.
&lt;p align=&quot;justify&quot;&gt;&lt;strong&gt;&lt;a href=&quot;/tutorial-4-building-the-yellow-pages-application/&quot; title=&quot;Tutorial 4: Building the Yellow Pages Application&quot;&gt;Tutorial 4:&lt;/a&gt;&lt;/strong&gt; This part focuses on all the code that is required to build this application.
&lt;p align=&quot;justify&quot;&gt;In each part I have provided a link to download source code also.
&lt;p align=&quot;justify&quot;&gt;This tutorials took a long time so if you find any error in this tutorial please feel free to give your suggestions.</content:encoded></item><item><title><![CDATA[Tutorial Start Page]]></title><link>https://pulkitgoyal.in/tutorial-start-page</link><guid isPermaLink="false">https://pulkitgoyal.in/tutorial-start-page</guid><pubDate>Tue, 24 May 2011 12:29:14 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Symbian is a proprietary operating system designed for mobile devices, with associated libraries, user interface, frameworks and reference implementations of common tools, developed by Symbian Ltd. It is a descendant of Psion&apos;s EPOC.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;A little history -- On 24 June 1998, Symbian Ltd. was formed as a partnership between Ericsson, Nokia, Motorola, and Psion, to exploit the convergence between PDAs and mobile phones. Symbian was previously owned by Nokia (56.3%), Ericsson (15.6%), Sony Ericsson (13.1%), Panasonic (10.5%), and Samsung (4.5%). Ten years later to the day, on 24 June 2008, Nokia announced that they intended to acquire all shares that they did not already own. Subsequently, Nokia opened up the development of Symbian to the broad industry by creating the &lt;a href=&quot;https://www.symbian.org/index.php&quot;&gt; Symbian Foundation&lt;/a&gt;.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;In this tutorial,we describe how to get started with Symbian Programming by taking you through the installation steps, and then taking through the design of a sample application. This tutorial assumes that you have worked with C++ before and have a brief knowledge about classes, inheritence etc. If you are facing problems with these topics, please dont start this tutorial before making those concepts clear. This tutorial requires no previous knowledge about Symbian and will be taking you forward from the beginning. The first section in this tutorial describes the installation of the development environment for Symbian Programming and the second part starts from a top down class design for a sample application.&lt;/p&gt;
&lt;h2&gt;Getting Started: Hardware and SDK Installation&lt;/h2&gt;
&lt;h3&gt;&lt;/h3&gt;
&lt;h3&gt;&lt;strong&gt;Part 1: The Hardware&lt;/strong&gt;&lt;/h3&gt;
&lt;p align=&quot;justify&quot;&gt;The first thing you need is a PC/Monitor/mouse and Keyboard. Almost any machine on market today can be used for development, however some would save you a bit of time:&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;Don&apos;t pay too much attention to the CPU (just avoid if you can the entry level Celeron and Sempron) but take as much RAM memory as you can. 1GB seems a minimal requirement if you consider doing serious development, a big fast hardisk (Speed is important to reduce compilation times and emulator start time, space is a requirement to handle all your SDKs. As an example, you will need 1GB for the S60 3rd FP1 SDK, 500MB for Carbide.c++, etc...). also avoid Windows Vista for now, the ARM toolchain is not yet compatible with it. If everything is ok on the hardware/operating side, you are almost ready to start.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;one last thing to check: make sure you have enough space on your C: drive. This is not an absolute requirement, but if you don&apos;t want to bother mounting virtual drive and editing configuration files again and again, you will need to install everything, the IDE, the SDK(s), your project(s) on C: so a minimum of 2GB free space is required before starting installation (and this is a minimum!).&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Part 2: The software development toolchain&lt;/strong&gt;&lt;/h3&gt;
&lt;p align=&quot;justify&quot;&gt;Now let&amp;apos;s go for a bit of downloading. So download and install: &lt;a href=&quot;https://downloads.activestate.com/ActivePerl/Windows/5.6/ActivePerl-5.6.1.638-MSWin32-x86.msi&quot;&gt;ActivePerl v5.6.1&lt;/a&gt;. The latest 5.8 nor 5.10 versions won&amp;apos;t probably work.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;&amp;#xA0;&lt;a href=&quot;https://sw.nokia.com/id/7710eba7-4da7-4ddc-a52a-53b506cadb4a/Carbide_cpp_v2_0_en.exe&quot;&gt;The Carbide.c++ IDE.&lt;/a&gt; : Carbide.C++ is a software development tool for C++ development on Symbian OS. It is used to develop phones that use the OS, as well as applications that run on that phone. It is based on Eclipse IDE Platform enhanced with extra plugins to support Symbian OS development. The Express version (which is free) is enough if you are a student or just intend to learn Symbian OS development. The Developer version (or better) is required if you plan to do some commercial development.
To avoid any problem, be sure to install everything on C:&amp;#xA0; in their default location.&lt;/p&gt;
The Software Development Toolchain: The SDKs
&lt;p align=&quot;justify&quot;&gt;The S60 SDK : The S60 Platform (formerly Series 60 User Interface) is a software platform for mobile phones that runs on Symbian OS. S60 is currently amongst the leading smartphone platforms in the world. It is owned by Nokia. S60 is licensed by Nokia to other manufacturers including Lenovo, LG Electronics, Panasonic and Samsung.&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;Download &lt;a href=&quot;https://sw.nokia.com/id/577ad48d-290c-4bb5-8bdf-779ea8a5bc6c/S60_5th_Edition_SDK_v1_0_en.zip&quot;&gt;the S60 SDK.&lt;/a&gt; Install the SDK in its default directory and on the same drive as Carbide.c++ At the end of the installation, you will be prompted to install the CSL Arm Toolchain if it is not already installed on your machine. Make sure you install it or you won&amp;apos;t be able to compile for the phone target.&lt;/p&gt;
Reboot your machine
&lt;p align=&quot;justify&quot;&gt;The Software Development Toolchain: Checking the installation&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;At the command prompt type &amp;apos;epoc&amp;apos;. The S60 emulator window should come up.&lt;/p&gt;
&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/05/symbian.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-152&quot; title=&quot;Symbian&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_300,w_206/v1392235546/symbian_kh8muu.jpg&quot; alt width=&quot;206&quot; height=&quot;300&quot;&gt;&lt;/a&gt;
&lt;p&gt;The Software Development Toolchain: Reference Book :&lt;/p&gt;
&lt;p&gt;Developing Software for Symbian OS by Steve Babin.&lt;/p&gt;
&lt;p&gt;The Software Development Toolchain: Getting Help&lt;/p&gt;
&lt;p&gt;You can refer to following links for help in Symbian Programming&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.forum.nokia.com/&quot;&gt;Nokia Forums&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://www.newlc.com/+-Symbian-OS-+.html&quot;&gt;NewLC&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://developer.symbian.com/&quot;&gt;Symbian Developers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
For more help, you can look up the examples provided with Carbide.C++ and the SDK. Here are the instructions to running the Hello World example in Carbide.C++:
&lt;ul&gt;
	&lt;li&gt;Run Carbide.C++&lt;/li&gt;
	&lt;li&gt;Goto File -&amp;gt; Import&lt;/li&gt;
&lt;p align=&quot;justify&quot;&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/05/import.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-157&quot; title=&quot;import&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_300,w_256/v1392235545/import_w1lqmy.jpg&quot; alt width=&quot;256&quot; height=&quot;300&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;li&gt;Select Symbian OS -&amp;gt; Symbian OS Build.inf File and click on Next.Then browse to the directory where you installed Symbian SDK, and look for Examples in the subdirectories. The default location should be : C:Symbian9.2S60_3rd_FP1_3Examples. Once there, browse through Basics -&amp;gt; HelloWorld. Select the bld.inf file and proceed further.&lt;/li&gt;
&lt;p align=&quot;justify&quot;&gt;&lt;a href=&quot;https://wl37www31.webland.ch/wp-content/uploads/2011/05/path_to_bld.jpg&quot;&gt;&lt;img class=&quot;aligncenter size-medium wp-image-158&quot; title=&quot;path_to_bld&quot; src=&quot;https://res.cloudinary.com/http-pulkitgoyal-in/image/upload/h_251,w_300/v1392235544/path_to_bld_oi5zw0.jpg&quot; alt width=&quot;300&quot; height=&quot;251&quot;&gt;&lt;/a&gt;&lt;/p&gt;&lt;li&gt;Proceed through the next screens checking all the check boxes and then Run the Project by Pressing Ctrl+F11 or by selecting Run -&amp;gt; Run.&lt;/li&gt;
</content:encoded></item><item><title><![CDATA[Image Inpainting]]></title><link>https://pulkitgoyal.in/image-inpainting</link><guid isPermaLink="false">https://pulkitgoyal.in/image-inpainting</guid><pubDate>Sun, 09 Jan 2011 15:43:48 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Image Inpainting is the art of filling in lost portions of an image using background details in a visually plausible way. I came across this topic while searching for projects in the field of image processing for sixth semester. The moment I saw a few sample pictures, I decided that I was gonna work on it.
&lt;p align=&quot;justify&quot;&gt;As is quite clear from these images, a good and fast algorithm for Image Inpainting can be really useful. I worked with &lt;a href=&quot;https://sapandiwakar.in&quot;&gt;Sapan&lt;/a&gt; to develop the software. We started with a traditional algorithm but finally ended up making several changes to it in order to improve the results.
&lt;p&gt;Here’s a brief decription of the inpainting algorithm.&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Divide the marked region into patches.&lt;/li&gt;
	&lt;li&gt;Assign priorities to the patches (Using Data and Confidence Terms)&lt;/li&gt;
	&lt;li&gt;Choose patch with maximum priority and find a patch from background region that is most similar to the chosen patch&lt;/li&gt;
	&lt;li&gt;Replace the patch with the patch from background and update data and confidence values.&lt;/li&gt;
&lt;/ol&gt;
&lt;p align=&quot;justify&quot;&gt;This is a very brief overview of the inpainting algorithm. For more details, you may feel free to contact me or go through the &lt;a href=&quot;https://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=5673977&quot;&gt;research paper &lt;/a&gt;that we authored.
&lt;p align=&quot;justify&quot;&gt;For more information about the implementation, visit &lt;a href=&quot;https://sourceforge.net/projects/imageinpainting/&quot;&gt;our project page on Sourceforge&lt;/a&gt;. I hope that you would enjoy using it. It is still a very early release and we hope to improve on it soon. Looking forward to your participation on the project as well.
&lt;p&gt;See the software in action in this video.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=DHF6xX83uhM&quot;&gt;https://www.youtube.com/watch?v=DHF6xX83uhM&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Stay tuned for my next post. Meanwhile, tell me your suggestions/comments about my work.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Gaming Zone!]]></title><link>https://pulkitgoyal.in/gaming-zone</link><guid isPermaLink="false">https://pulkitgoyal.in/gaming-zone</guid><pubDate>Wed, 01 Dec 2010 00:04:02 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;Ever since my childhood, I have been very interested in computers, especially PC gaming. It all started with the small DOS based games like &lt;a href=&quot;https://en.wikipedia.org/wiki/Prince_of_Persia_(1989_video_game)&quot;&gt;Prince of Persia&lt;/a&gt; and &lt;a href=&quot;https://en.wikipedia.org/wiki/Dangerous_Dave&quot;&gt;Dave&lt;/a&gt;. I still remember beating all the levels in dave again and again. I wish I could get my hands on those games again. That&apos;s how my love for computer gaming began. Over the years, I have played several games. I have seen these games develop and the graphics, visual effects and artificial intelligence has improved dramatically.
&lt;p align=&quot;justify&quot;&gt;But my real gaming started only after getting admission into IIIT. First time when I saw my seniors play counter strike, I was amazed. It was so great watching all of them play together, shouting at each other, killing each other (in game of course :P). I was dying to play it. I started playing with a long name which eventually shortened down to &lt;strong&gt;(J5&lt;/strong&gt;. I was enjoying every moment of it. The team work, the strategy and the thrill. We used to play whole day and night.
&lt;p align=&quot;justify&quot;&gt;Meanwhile, my interest into Age of Empires 2: The Conquerers also developed into addiction. It was again thanks to the seniors, specially, Red Bull, Sa61e and SEXYSUNNY. I enjoyed watching their games and hoped that I would play like them one day. :) I was among the first few who started playing AOE in my batch, the others being &lt;a href=&quot;https://sapandiwakar.in&quot;&gt;Sapan&lt;/a&gt;, Varun and Arun.  I enjoyed playing AOE and CS a lot. We played a lot with each other and with the seniors and  super seniors. I still remember the game that I and Sapan played against LunePredator and Vivek Sir. We had no idea how good they were at age and thus started playing a 2 on 2 match with them. And as it always happens in matches between seniors and juniors, we were brutally destroyed :(. That&apos;s how our journey began with AOE and we gradually improved and started giving good fight to our seniors :D.
&lt;p align=&quot;justify&quot;&gt;Enough about AOE. I also enjoyed playing FIFA. My interest for FIFA had begun long before I had joined the college. But after joining IIITA, it grew much larger. I enjoyed playing it on LAN with my colleagues. I participated in the tournament that seniors organized as well as our batch tournament and enjoyed every single match. Gaming has always been my passion and will remain for a long time. PC gaming is a great experience and I believe that it is something that everybody should try to do at least once. :D</content:encoded></item><item><title><![CDATA[Joining Sun Family]]></title><link>https://pulkitgoyal.in/joining-sun-family</link><guid isPermaLink="false">https://pulkitgoyal.in/joining-sun-family</guid><pubDate>Mon, 29 Nov 2010 18:19:41 GMT</pubDate><content:encoded>&lt;p align=&quot;justify&quot;&gt;This story begins with a mail from our Dean Student Affairs, Prof. G.C. Nandi. I was told to send my resume to him. At that time, I was unaware about what it was for. Later, I came to know that it was for the post of Sun Campus Ambassador for my campus. I was very excited about it. But at the same time, I was worried. It was the first interview that I was going to face. They had scheduled a telephonic interview for me with a Sun Engineer. I was in my third semester then and didn&apos;t know much about interviews. I had no idea about what it was going to be like.
&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;
So, in complete ignorance, I waited for the day of interview. She started the interview with some general questions and then slowly came towards technical questions. It was a nice experience which lasted for about 30 minutes. After a few days, I received a call telling that I had been selected as the Sun Campus Ambassador. I was very excited. I had never dreamed that I would be promoting Sun Microsystems in my campus. With this began my wonderful journey as a Sun Campus Ambassador. :)
&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;
After a few days, I received a letter from Sun Microsystems about my responsibilities and my salary ;). This was how I became a part of the Sun Microsystems family. I began by organizing a few presentations about Sun products. I was amazed at the wonderful responses of my colleagues.  I also arranged a special screening of Glassfish Webinar organized by Sun. Motivated with the success, I along with my roommate &lt;a href=&quot;https://sapandiwakar.in&quot;&gt;Sapan&lt;/a&gt;, organized a Free and Open Source Software (FOSS) Quiz. It attracted a lot of students. Our complete B2k7 batch and most of my seniors and juniors participated in the quiz. All the prizes, including 6 pen drives for the top 3 teams and various other goodies were sponsored by Sun Microsystems.
&lt;/p&gt;
&lt;p align=&quot;justify&quot;&gt;
I enjoyed every moment as a Sun Campus Ambassador. After the merger of Sun and Oracle, I acquired the role of OSUM Affiliate Leader for my campus as a part of which I promoted various Sun and other Free and Open Source Softwares.  We also arranged another FOSS quiz which was also very successful.
&lt;/p&gt;</content:encoded></item></channel></rss>