<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Michal Rogowski</title>
    <description>The latest articles on DEV Community by Michal Rogowski (@michalrogowski).</description>
    <link>https://dev.to/michalrogowski</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F212654%2F2a3391e6-2a05-44da-bdb3-8d108d3f9411.jpeg</url>
      <title>DEV Community: Michal Rogowski</title>
      <link>https://dev.to/michalrogowski</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michalrogowski"/>
    <language>en</language>
    <item>
      <title>Optimize your website to get more AI citations</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Mon, 29 Sep 2025 19:52:07 +0000</pubDate>
      <link>https://dev.to/michalrogowski/optimize-your-website-to-get-more-ai-citations-32d5</link>
      <guid>https://dev.to/michalrogowski/optimize-your-website-to-get-more-ai-citations-32d5</guid>
      <description>&lt;h2&gt;
  
  
  Why should you care about AI Chatbots?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.gartner.com/en/newsroom/press-releases/2024-02-19-gartner-predicts-search-engine-volume-will-drop-25-percent-by-2026-due-to-ai-chatbots-and-other-virtual-agents?ref=beyondsenior.engineering" rel="noopener noreferrer"&gt;By 2026 25%&lt;sup&gt;[1]&lt;/sup&gt;&lt;/a&gt; of users will migrate their regular Search experience to &lt;strong&gt;AI chatbots and agents&lt;/strong&gt;. This creates new risks and opportunities for all companies, people and websites producing publicly available content to increase their organic growth.&lt;/p&gt;

&lt;p&gt;In order for our business to stay relevant and be discovered by new audiences we have to understand how AI chatbots generate their responses.&lt;/p&gt;




&lt;h2&gt;
  
  
  How AI Chatbots generate their responses
&lt;/h2&gt;

&lt;p&gt;The response from the AI Chatbot is created based on three different stages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;LLM model Training:&lt;/strong&gt; The foundational knowledge of the model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scanning:&lt;/strong&gt; AI bot’s crawling the internet for up-to-date information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retrieval:&lt;/strong&gt; Selecting the most relevant chunks from its database to answer the user query.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How to Optimize your website to get more AI citations?
&lt;/h2&gt;

&lt;p&gt;Focus on &lt;a href="https://en.wikipedia.org/wiki/Generative_engine_optimization" rel="noopener noreferrer"&gt;&lt;strong&gt;Generative Engine Optimization (GEO)&lt;/strong&gt;&lt;/a&gt;. You do this by creating a website and content that demonstrates high &lt;a href="https://developers.google.com/search/blog/2022/12/google-raters-guidelines-e-e-a-t" rel="noopener noreferrer"&gt;&lt;strong&gt;E-E-A-T&lt;/strong&gt; (Experience, Expertise, Authoritativeness, and Trust) &lt;sup&gt;[13]&lt;/sup&gt;&lt;/a&gt; scores, which AI crawlers use to evaluate and select content to be cited in their responses.&lt;/p&gt;

&lt;p&gt;Key principles for achieving this include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Demonstrating E-E-A-T:&lt;/strong&gt; Prove your credibility through first-hand experience, author expertise, brand authority, and building trust with verifiable claims and citations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear Page and Content Structure:&lt;/strong&gt; Use clear HTML tags, relevant metadata, and a logical content flow with headings and an "answers-first" approach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Freshness:&lt;/strong&gt; Ensure your content and metadata are up to date, as this has a significant impact on citation rates.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By following these rules, you increase the citation impact by AI chatbots, which boosts your organic traffic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deep Dive: How AI Chatbots Generate Responses
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. LLM model Training
&lt;/h3&gt;

&lt;p&gt;The first way your data may become part of a chatbot answer is by being included in its training data. From a company perspective, there are no direct benefits if content is scraped for training, as the output doesn't contain citations, links, or author information. This has led to &lt;a href="https://en.wikipedia.org/wiki/Artificial_intelligence_and_copyright" rel="noopener noreferrer"&gt;lawsuits over copyrighted data&lt;sup&gt;[3]&lt;/sup&gt;&lt;/a&gt;. The training data allows LLMs to sound human and structure answers, but it's prone to &lt;a href="https://en.wikipedia.org/wiki/Hallucination_(artificial_intelligence)" rel="noopener noreferrer"&gt;hallucinations&lt;sup&gt;[6]&lt;/sup&gt;&lt;/a&gt; and has a hard cut-off date. Companies with high-quality data are now making deals with AI firms, like &lt;a href="https://openai.com/index/openai-and-reddit-partnership/" rel="noopener noreferrer"&gt;Reddit with OpenAI&lt;sup&gt;[7]&lt;/sup&gt;&lt;/a&gt; or &lt;a href="https://wikimediafoundation.org/news/2022/06/21/wikimedia-enterprise-announces-google-and-internet-archive-first-customers/" rel="noopener noreferrer"&gt;Wikimedia Enterprise and Google&lt;sup&gt;[8]&lt;/sup&gt;&lt;/a&gt;. The lesson: if you have valuable human generated data, sell it, don't give it away for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Scanning - AI bot’s crawling the internet
&lt;/h3&gt;

&lt;p&gt;This is the most important step for website creators. &lt;a href="https://arxiv.org/abs/2005.11401" rel="noopener noreferrer"&gt;In 2020, Meta’s research team introduced&lt;/a&gt; &lt;a href="https://cloud.google.com/use-cases/retrieval-augmented-generation" rel="noopener noreferrer"&gt;&lt;strong&gt;Retrieval-Augmented Generation (RAG)&lt;/strong&gt;&lt;sup&gt;[9, 10]&lt;/sup&gt;&lt;/a&gt;. RAG allows AI chatbots to access up-to-date, hallucination-free information. Before retrieval, AI companies use &lt;a href="https://blog.cloudflare.com/ai-crawler-traffic-by-purpose-and-industry/" rel="noopener noreferrer"&gt;crawlers&lt;sup&gt;[11]&lt;/sup&gt;&lt;/a&gt; to scan the internet, identify relevant pages, and store them as data chunks for their RAG pipelines. During this scan, they evaluate a page's &lt;strong&gt;E-E-A-T&lt;/strong&gt; and its &lt;a href="https://arxiv.org/html/2403.18350v2" rel="noopener noreferrer"&gt;semantic meaning&lt;sup&gt;[12]&lt;/sup&gt;&lt;/a&gt; for deep contextual understanding. To appear in AI chatbot citations, we must focus on Generative Engine Optimization (GEO).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Retrieval
&lt;/h3&gt;

&lt;p&gt;Once your website has been scanned, chunked, associated with a high E-E-A-T score and stored in the vector DB, it can be retrieved to answer a user's query. The content is slightly changed when presented, but your page is credited and listed as a source. This is how we can grow organic traffic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx9e3zv0qkfojgsrqehh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx9e3zv0qkfojgsrqehh.png" alt="A flowchart of the RAG process. It shows a user prompt going to a retrieval system, which pulls data from a vector database. The prompt and data are then fed into an LLM to produce a final, context-aware answer." width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Create GEO-optimized sites with high E-E-A-T scores
&lt;/h2&gt;

&lt;p&gt;Defining the brand’s Experience, Expertise, Authoritativeness and Trust.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://developers.google.com/search/blog/2022/12/google-raters-guidelines-e-e-a-t" rel="noopener noreferrer"&gt;Experience&lt;sup&gt;[13]&lt;/sup&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The focus here is on demonstrating first-hand experience with the topic. For example: "while working with our clients, we noticed the exact pattern how our GEO strategy increases their traffic from AI Chatbots by 30%." The engine can detect that you have real-world experience on the topic at hand.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Expertise
&lt;/h3&gt;

&lt;p&gt;The next parameter influencing &lt;a href="https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf" rel="noopener noreferrer"&gt;Page Quality (PQ)&lt;sup&gt;[14]&lt;/sup&gt;&lt;/a&gt; rating is expertise. This is about how qualified you are to express opinions. The page should include information about the author. For example, my &lt;a href="https://www.linkedin.com/in/rogowski-michal/" rel="noopener noreferrer"&gt;professional profile&lt;sup&gt;[15]&lt;/sup&gt;&lt;/a&gt; is linked, which connects to my LinkedIn, showing my expertise as a Senior Engineering Manager is relevant to topics like LLMs and AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Authoritativeness
&lt;/h3&gt;

&lt;p&gt;This refers to the reputation of the brand or website. As &lt;a href="https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf" rel="noopener noreferrer"&gt;Google's guidelines&lt;sup&gt;[16]&lt;/sup&gt;&lt;/a&gt; state, the authority on getting French citizenship is the French government's website, giving it high authoritativeness on that specific process.&lt;/p&gt;

&lt;p&gt;To illustrate the overlap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Experience:&lt;/strong&gt; Written by someone who has applied for citizenship, sharing their personal journey.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expertise:&lt;/strong&gt; Written by an immigration lawyer who specializes in the process.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authoritativeness:&lt;/strong&gt; The official government page that sets the rules for citizenship.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Trust
&lt;/h3&gt;

&lt;p&gt;This is the most important parameter of E-E-A-T. If your brand is perceived as a scam, you can't make up for it with expertise or experience. Trust is built on what others write about you and whether you are referenced as a source of truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Can you use Generative AI?
&lt;/h3&gt;

&lt;p&gt;According to &lt;a href="https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf" rel="noopener noreferrer"&gt;Google's guidelines&lt;sup&gt;[16]&lt;/sup&gt;&lt;/a&gt;, if you use Generative AI to create high-value content that upholds all four aspects of E-E-A-T, it's acceptable. If you use it to generate low-quality content, your score will decrease.&lt;/p&gt;




&lt;h2&gt;
  
  
  Core Generative Engine Optimisation Principles
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Authority &amp;amp; Trust
&lt;/h3&gt;

&lt;p&gt;The core objective for AI Chatbots is to minimize hallucinations. You can increase your authority and trust by making claims verifiable and providing evidence from respectable sources. Research from &lt;a href="https://arxiv.org/html/2509.10762v1" rel="noopener noreferrer"&gt;Berkeley&lt;sup&gt;[17]&lt;/sup&gt;&lt;/a&gt; introduces a 16-pillar auditing framework that converts page features into a normalized GEO score.&lt;/p&gt;

&lt;h3&gt;
  
  
  Page Structure
&lt;/h3&gt;

&lt;p&gt;Ensure a clear code structure for machines. Use relevant HTML tags like &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;h2&amp;gt;&lt;/code&gt;, internal OG tags, and JSON-LD. Following HTML &lt;a href="https://www.w3schools.com/html/html_accessibility.asp" rel="noopener noreferrer"&gt;accessibility guidelines&lt;sup&gt;[18]&lt;/sup&gt;&lt;/a&gt; is a good start. An example of well-structured &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; content may look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Optimize your website for AI to get more citations | Beyond Senior Engineering&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Learn how to optimize your website for AI and Generative Engine Optimization (GEO) to get more citations and increase authority."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:type"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"article"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:url"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"[https://www.beyondsenior.engineering/articles/optimise-your-website-for-AI-to-get-more-citations.html](https://www.beyondsenior.engineering/articles/optimise-your-website-for-AI-to-get-more-citations.html)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Optimise your website for AI to get more citations."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Learn how to optimize your website for AI and Generative Engine Optimization (GEO) to get more citations and increase authority."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"og:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"[https://www.beyondsenior.engineering/images/rag-process-diagram.png](https://www.beyondsenior.engineering/images/rag-process-diagram.png)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"article:published_time"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"2025-09-29T09:00:00+00:00"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;property=&lt;/span&gt;&lt;span class="s"&gt;"article:author"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"[https://www.beyondsenior.engineering/author.html](https://www.beyondsenior.engineering/author.html)"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:card"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"summary_large_image"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:title"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Optimise your website for AI to get more citations."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:description"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"Learn how to optimize your website for AI and Generative Engine Optimization (GEO) to get more citations and increase authority."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"twitter:image"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"[https://www.beyondsenior.engineering/images/rag-process-diagram.png](https://www.beyondsenior.engineering/images/rag-process-diagram.png)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"application/ld+json"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@context&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://schema.org](https://schema.org)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;BlogPosting&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;headline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Optimise your website for AI to get more citations.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://www.beyondsenior.engineering/articles/optimise-your-website-for-AI-to-get-more-citations.html](https://www.beyondsenior.engineering/articles/optimise-your-website-for-AI-to-get-more-citations.html)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;datePublished&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2025-09-29T09:00:00+00:00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://www.beyondsenior.engineering/images/rag-process-diagram.jpg](https://www.beyondsenior.engineering/images/rag-process-diagram.jpg)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;author&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Person&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Michal Rogowski&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://www.beyondsenior.engineering/author.html](https://www.beyondsenior.engineering/author.html)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;publisher&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Organization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Beyond Senior Engineering&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;logo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ImageObject&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;url&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;[https://www.beyondsenior.engineering/images/logo.png](https://www.beyondsenior.engineering/images/logo.png)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Content Structure
&lt;/h3&gt;

&lt;p&gt;The more structured the content, with clear headers, sub-headers, questions, and answers, the easier it is for the RAG process to assign correct semantic meaning. &lt;a href="https://arxiv.org/html/2509.10762v1" rel="noopener noreferrer"&gt;Lead with an "answers-first" summary&lt;sup&gt;[17]&lt;/sup&gt;.&lt;/a&gt; Use an &lt;a href="https://www.reddit.com/r/PeterAttia/comments/1cdtbt0/what_does_strong_convictions_loosely_held_even/" rel="noopener noreferrer"&gt;active voice, as crawlers prefer trustworthy certainty over opinion&lt;sup&gt;[19]&lt;/sup&gt;.&lt;/a&gt; Finally, ensure the content is fresh. Metadata and &lt;a href="https://arxiv.org/html/2509.10762v1" rel="noopener noreferrer"&gt;freshness have the biggest citation impact, at +47%&lt;sup&gt;[17]&lt;/sup&gt;.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To make this more actionable, you can inspect the code of this page and analyze its structure. You can see that this entire essay was optimized to increase E-E-A-T and GEO scores. I hope that helps!&lt;/p&gt;

&lt;p&gt;Thanks,&lt;/p&gt;

&lt;p&gt;Michal.&lt;/p&gt;

&lt;p&gt;Citations&lt;br&gt;
[1] &lt;a href="https://www.gartner.com/en/newsroom/press-releases/2024-02-19-gartner-predicts-search-engine-volume-will-drop-25-percent-by-2026-due-to-ai-chatbots-and-other-virtual-agents?ref=beyondsenior.engineering" rel="noopener noreferrer"&gt;https://www.gartner.com/en/newsroom/press-releases/2024-02-19-gartner-predicts-search-engine-volume-will-drop-25-percent-by-2026-due-to-ai-chatbots-and-other-virtual-agents?ref=beyondsenior.engineering&lt;/a&gt;&lt;br&gt;
[2] &lt;a href="https://en.wikipedia.org/wiki/Generative_engine_optimization" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Generative_engine_optimization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href="https://en.wikipedia.org/wiki/Artificial_intelligence_and_copyright" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Artificial_intelligence_and_copyright&lt;/a&gt;&lt;br&gt;
[4] &lt;a href="https://www.theguardian.com/technology/2025/sep/05/anthropic-settlement-ai-book-lawsuit" rel="noopener noreferrer"&gt;https://www.theguardian.com/technology/2025/sep/05/anthropic-settlement-ai-book-lawsuit&lt;/a&gt;&lt;br&gt;
[5] &lt;a href="https://meta.wikimedia.org/wiki/Research:Large_Language_Models_(LLMs)_Impact_on_Wikipedia's_Sustainability" rel="noopener noreferrer"&gt;https://meta.wikimedia.org/wiki/Research:Large_Language_Models_(LLMs)_Impact_on_Wikipedia's_Sustainability&lt;/a&gt;&lt;br&gt;
[6] &lt;a href="https://en.wikipedia.org/wiki/Hallucination_(artificial_intelligence)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Hallucination_(artificial_intelligence)&lt;/a&gt;&lt;br&gt;
[7] &lt;a href="https://openai.com/index/openai-and-reddit-partnership/" rel="noopener noreferrer"&gt;https://openai.com/index/openai-and-reddit-partnership/&lt;/a&gt;&lt;br&gt;
[8] &lt;a href="https://wikimediafoundation.org/news/2022/06/21/wikimedia-enterprise-announces-google-and-internet-archive-first-customers/" rel="noopener noreferrer"&gt;https://wikimediafoundation.org/news/2022/06/21/wikimedia-enterprise-announces-google-and-internet-archive-first-customers/&lt;/a&gt;&lt;br&gt;
[9] &lt;a href="https://arxiv.org/abs/2005.11401" rel="noopener noreferrer"&gt;https://arxiv.org/abs/2005.11401&lt;/a&gt;&lt;br&gt;
[10] &lt;a href="https://cloud.google.com/use-cases/retrieval-augmented-generation" rel="noopener noreferrer"&gt;https://cloud.google.com/use-cases/retrieval-augmented-generation&lt;/a&gt;&lt;br&gt;
[11] &lt;a href="https://blog.cloudflare.com/ai-crawler-traffic-by-purpose-and-industry/" rel="noopener noreferrer"&gt;https://blog.cloudflare.com/ai-crawler-traffic-by-purpose-and-industry/&lt;/a&gt;&lt;br&gt;
[12] &lt;a href="https://arxiv.org/html/2403.18350v2" rel="noopener noreferrer"&gt;https://arxiv.org/html/2403.18350v2&lt;/a&gt;&lt;br&gt;
[13] &lt;a href="https://developers.google.com/search/blog/2022/12/google-raters-guidelines-e-e-a-t" rel="noopener noreferrer"&gt;https://developers.google.com/search/blog/2022/12/google-raters-guidelines-e-e-a-t&lt;/a&gt;&lt;br&gt;
[14] &lt;a href="https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf" rel="noopener noreferrer"&gt;https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf&lt;/a&gt;&lt;br&gt;
[15] &lt;a href="https://www.linkedin.com/in/rogowski-michal/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/rogowski-michal/&lt;/a&gt;&lt;br&gt;
[16] &lt;a href="https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf" rel="noopener noreferrer"&gt;https://static.googleusercontent.com/media/guidelines.raterhub.com/en//searchqualityevaluatorguidelines.pdf&lt;/a&gt;&lt;br&gt;
[17] &lt;a href="https://arxiv.org/html/2509.10762v1" rel="noopener noreferrer"&gt;https://arxiv.org/html/2509.10762v1&lt;/a&gt;&lt;br&gt;
[18] &lt;a href="https://www.w3schools.com/html/html_accessibility.asp" rel="noopener noreferrer"&gt;https://www.w3schools.com/html/html_accessibility.asp&lt;/a&gt;&lt;br&gt;
[19] &lt;a href="https://www.reddit.com/r/PeterAttia/comments/1cdtbt0/what_does_strong_convictions_loosely_held_even/" rel="noopener noreferrer"&gt;https://www.reddit.com/r/PeterAttia/comments/1cdtbt0/what_does_strong_convictions_loosely_held_even/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>seo</category>
      <category>rag</category>
    </item>
    <item>
      <title>Delegate Well – Why Smart Leaders Delegate More!</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sun, 01 Dec 2024 10:41:07 +0000</pubDate>
      <link>https://dev.to/michalrogowski/delegate-well-why-smart-ceos-delegate-more-49p3</link>
      <guid>https://dev.to/michalrogowski/delegate-well-why-smart-ceos-delegate-more-49p3</guid>
      <description>&lt;p&gt;Ever wondered what separates thriving companies from struggling ones? Research by Gallup reveals CEOs who effectively delegate see a 33% boost in revenue. The secret lies in creating owners, scaling intelligently, and empowering teams.&lt;/p&gt;

&lt;p&gt;Hi, I’m Michal, a software engineering manager with over a decade of experience. Today, I’ll share how delegation transformed my leadership approach and why it’s a game-changer for businesses, leaders, and teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Delegation Helps You Focus on What Matters
&lt;/h2&gt;

&lt;p&gt;Let’s face it—no one can do everything. Delegation frees you to focus on what you’re good at and passionate about. Using the Love/Competence Matrix, you can quickly decide what to keep and what to pass on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Love &amp;amp; Competent?&lt;/strong&gt; Do it yourself—this is your zone of genius.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dislike &amp;amp; Incompetent?&lt;/strong&gt; Delegate ASAP. Example: I delegated Confluence maintenance because, well, I thrive in chaos, not documentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good at but Dislike?&lt;/strong&gt; Delegate to avoid burnout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Love but Not Good At?&lt;/strong&gt; Use this as a growth opportunity—take it on strategically.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlc9uf64b5m0kjgm19q6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdlc9uf64b5m0kjgm19q6.png" alt="Image description" width="800" height="671"&gt;&lt;/a&gt;&lt;br&gt;
By offloading tasks outside your sweet spot, you’ll not only stay energized but also open space for strategic growth.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Delegation Scales Your Business
&lt;/h2&gt;

&lt;p&gt;Delegation isn’t just about offloading work—it’s a business multiplier. I call this the Delegation Circle:&lt;br&gt;
&lt;strong&gt;Delegate → Empower Owners → Faster Decisions → Greater Results → Bigger Profits.&lt;/strong&gt;&lt;br&gt;
The key? Avoid bottlenecks by ensuring ownership matches capability. If team members aren’t empowered to lead, scaling leads to chaos, not growth.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fum449rirx25todfutec6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fum449rirx25todfutec6.png" alt="Image description" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Delegation Grows Your Team
&lt;/h2&gt;

&lt;p&gt;Delegation is the ultimate tool for professional growth. Using my Seniority/Potential Matrix, you can match tasks to people based on their experience and growth potential:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;High seniority?&lt;/strong&gt; Assign well-defined, impactful tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High potential but less experience?&lt;/strong&gt; Provide smaller, structured challenges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Balance is key—offer enough stretch to foster growth but enough support to ensure success. Remember: stretching tasks require guidance, not micromanagement.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklq17m2xs6bqqsm96wnj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fklq17m2xs6bqqsm96wnj.png" alt="Image description" width="800" height="745"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Matters
&lt;/h2&gt;

&lt;p&gt;As Bill Gates said&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Leaders are those who empower others.&lt;br&gt;
Delegation is how you empower, scale, and grow.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Want to start today? Map your weekly tasks, categorize them, and apply the Love/Competence Matrix. Then, align tasks with your team’s Seniority/Potential Matrix for maximum impact.&lt;/p&gt;

&lt;p&gt;Ready to take your leadership to the next level? &lt;br&gt;
I talk about this stuff on my &lt;a href="http://youtube.com/@BeyondSeniorEngineering" rel="noopener noreferrer"&gt;YouTube Channel&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Empower your team. Scale your business. Grow as a leader. Let’s delegate well.&lt;/p&gt;

</description>
      <category>management</category>
      <category>leadership</category>
      <category>career</category>
    </item>
    <item>
      <title>7 months ago I published the app that allows you to adjust your WebCamera exposure - those are the stats!</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sat, 15 Jan 2022 17:26:43 +0000</pubDate>
      <link>https://dev.to/michalrogowski/7-months-ago-i-published-the-app-that-allows-you-to-adjust-your-webcamera-exposure-and-makes-your-face-visible-during-the-calls-10og</link>
      <guid>https://dev.to/michalrogowski/7-months-ago-i-published-the-app-that-allows-you-to-adjust-your-webcamera-exposure-and-makes-your-face-visible-during-the-calls-10og</guid>
      <description>&lt;p&gt;About a year ago during my 1:1 my boss told me that my face is barely visible because of the window in the background and that I should do something about it. Obviously I bough some apps in the Mac App Store - but all of them were not supporting my web camera. As an engineering manager and ex iOS software engineer I decided that I have to fix it and I've build the new app that would support most of the web cameras because of it's primitive functionality and that's how &lt;a href="https://apps.apple.com/pl/app/exposure-adjustor/id1570960511?mt=12" rel="noopener noreferrer"&gt;Exposure Adjustor&lt;/a&gt; was born.&lt;/p&gt;

&lt;p&gt;So the idea is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cover (with your hand) the part of your camera(lens) that is exposed to too much light&lt;/li&gt;
&lt;li&gt;Press Lock button to "lock" the current exposure&lt;/li&gt;
&lt;li&gt;Enjoy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Till now I haven't advertise my app in any way and those are the stats: (I released 7 months ago)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sales: 98.94$&lt;/li&gt;
&lt;li&gt;Proceeds: 76.83$&lt;/li&gt;
&lt;li&gt;Units: 44

&lt;ul&gt;
&lt;li&gt;Europe - 19&lt;/li&gt;
&lt;li&gt;USA &amp;amp; Canada - 17&lt;/li&gt;
&lt;li&gt;Asia Pacific - 6&lt;/li&gt;
&lt;li&gt;Latin America &amp;amp; The Caribbean - 2&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Rating: 5.0 (3 reviews 😂)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;This is the first app I've done and published for myself and not for the company or a client. Every sale is surprisingly satisfying and makes me really happy that someone is able to use it and is happy with what they've bought - I got 2 emails saying that it's a very cool app as it does exactly what it says on the tin.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>product</category>
      <category>swift</category>
    </item>
    <item>
      <title>CV's Absurd</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sun, 31 Oct 2021 10:44:42 +0000</pubDate>
      <link>https://dev.to/michalrogowski/cvs-absurd-32mk</link>
      <guid>https://dev.to/michalrogowski/cvs-absurd-32mk</guid>
      <description>&lt;p&gt;One of the responsibilities I have as an Engineering Manager in YouGov is being also a hiring manager for my team. I'm responsible for the process because I care to find a correct balance between skills &amp;amp; the need for more engineers (&lt;a href="https://jobs.yougov.com" rel="noopener noreferrer"&gt;Open Positions&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1454293034179317764-966" src="https://platform.twitter.com/embed/Tweet.html?id=1454293034179317764"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1454293034179317764-966');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1454293034179317764&amp;amp;theme=dark"
  }



&lt;br&gt;
When I've read a Reddit &lt;a href="https://www.reddit.com/r/recruitinghell/comments/qhg5jo/this_resume_got_me_an_interview/" rel="noopener noreferrer"&gt;thread&lt;/a&gt; about a software engineer who got tired of getting rejected by automated screeners and filled their CV with absurd information they got a 90% call back rate from companies like Reddit, AirTable, Dropbox, Bolt, Robinhood, and others I was like&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.giphy.com%2Fmedia%2FJ34ARJKZmxZACE7DvJ%2Fgiphy.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.giphy.com%2Fmedia%2FJ34ARJKZmxZACE7DvJ%2Fgiphy.webp" alt="WTF" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
   
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Reality check
&lt;/h3&gt;

&lt;p&gt;I've heard about these tools before, but I wasn't aware of how strict the rules are to get a good score.&lt;br&gt;
I liked my CV because I got positive feedback about it from different recruiters which actually read it, so I've put my CV into the free evaluating tool available &lt;a href="https://resumeworded.com/" rel="noopener noreferrer"&gt;online&lt;/a&gt;, and my CV's initial score was 23/100 😱!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rogowski.page%2Fimages%2FScreenshot%25202021-10-31%2520at%252010.43.48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rogowski.page%2Fimages%2FScreenshot%25202021-10-31%2520at%252010.43.48.png" alt="score" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I assume I wouldn't receive a call from any company that is using the screening tool - which sucks. After spending 15 minutes and making some quick fixes (mostly structure) I re-tested my CV and my score was 67.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rogowski.page%2Fimages%2FScreenshot%25202021-10-31%2520at%252011.03.13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.rogowski.page%2Fimages%2FScreenshot%25202021-10-31%2520at%252011.03.13.png" alt="score" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now I have to focus on the impact section and I can probably go much higher without lying -but I liked the CV before changes more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Transparency
&lt;/h3&gt;

&lt;p&gt;We all want to reduce bias in our recruitment process - me too.&lt;br&gt;
Automating stuff seems like a really good idea because algorithms are not biased, except the process still is. People which know about the ATS (Applicant Tracking System) vs people which don't and are not aware of how relevant it is.&lt;/p&gt;

&lt;p&gt;What would be great is to be more transparent with candidates and if they were rejected because their CV didn't go through the automation we should just tell them that. We can even provide automated feedback to them, the same as some companies do with automated tasks &amp;amp; assignments. But transparency should be a Two-Way street, and if you plan to lie in your CV please don't, the company will find out anyway through assignment or interview but everyone will waste their time already.&lt;/p&gt;

&lt;p&gt;So if you didn't hear back from the big company you would love to work for don't worry maybe just tweak your CV :).&lt;/p&gt;

</description>
      <category>recruitment</category>
      <category>cv</category>
      <category>career</category>
      <category>news</category>
    </item>
    <item>
      <title>Personal CV page</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Wed, 09 Jun 2021 21:08:12 +0000</pubDate>
      <link>https://dev.to/michalrogowski/personal-cv-page-3co8</link>
      <guid>https://dev.to/michalrogowski/personal-cv-page-3co8</guid>
      <description>&lt;h2&gt;
  
  
  Given
&lt;/h2&gt;

&lt;p&gt;While I was working on my macOS app &lt;a href="https://apps.apple.com/us/app/exposure-adjustor/id1570960511?mt=12" rel="noopener noreferrer"&gt;Exposure Adjustor&lt;/a&gt;. I forgot that in order to upload it to the App Store I have to provide a Support URL, Marketing URL and Privacy Policy URL. Till now it wasn't a problem all of the apps that I've published were done for big companies that already had a website legal notes etc. The Exposure Adjustor allows you to lock the exposure of your camera to make sure that your face is visible even if there is direct sun or window behind you.&lt;/p&gt;

&lt;p&gt;I decided to take this opportunity and create a personal CV page you can check it here &lt;a href="https://rogowski.page" rel="noopener noreferrer"&gt;rogowski.page&lt;/a&gt;, where I can also link and publish my articles (I'm not writing too often but it's nice to have your personal space till now I was only publishing on dev.to). I decided to share my experience because with static site generator frameworks it's cheap and easy to do it in one day.&lt;/p&gt;

&lt;h2&gt;
  
  
  When
&lt;/h2&gt;

&lt;p&gt;I bought the domain on &lt;a href="http://www.ovh.com" rel="noopener noreferrer"&gt;www.ovh.com&lt;/a&gt; they have this nice plan where you can buy a domain with a &lt;strong&gt;free&lt;/strong&gt; hosting included it's called Start10M solution and is described &lt;a href="https://docs.ovh.com/gb/en/hosting/activate-start10m/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. As they are writing on their page &lt;/p&gt;

&lt;p&gt;&lt;em&gt;With Start10M, OVHcloud gives you a 10MB Web Hosting plan, and an email account with 5GB storage.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So the only cost is the cost of the domain itself. &lt;/p&gt;

&lt;p&gt;Because of the hosting plan limitations, I used a static site generator framework. I have some experience with other frameworks like &lt;a href="https://www.11ty.dev" rel="noopener noreferrer"&gt;11ty&lt;/a&gt; and integrating it with &lt;a href="https://docs.gitlab.com/ee/user/project/pages/" rel="noopener noreferrer"&gt;GitLab Pages&lt;/a&gt; but I like to try new technologies so this time I used &lt;a href="https://gohugo.io" rel="noopener noreferrer"&gt;hugo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I searched through some themes but finally, I decided to use beautiful theme called &lt;a href="https://themes.gohugo.io/almeida-cv/" rel="noopener noreferrer"&gt;almeida-cv&lt;/a&gt;. It's a clean nice looking CV format page but the thing that it was missing was the possibility to list my articles.&lt;/p&gt;

&lt;p&gt;I didn't want to add the navigation header on top because it would destroy the CV paper feeling that I liked, so I decided to list the last 5 articles that I've written. I also did some fixes to the layout especially on mobile devices. I decided that the CV look is less important than readability.&lt;/p&gt;

&lt;p&gt;To upload the page to the server I'm using the open-source &lt;a href="https://cyberduck.io" rel="noopener noreferrer"&gt;cyberduck&lt;/a&gt; app and it's great and easy to use. &lt;/p&gt;

&lt;h2&gt;
  
  
  Then
&lt;/h2&gt;

&lt;p&gt;I think creating such page is a great way to improve your personal branding because you can put much more information on the web page than in an actual CV. I will update you on statistics in the future, I linked this page in my &lt;a href="https://www.linkedin.com/in/rogowski-michal/" rel="noopener noreferrer"&gt;LinkedIn account&lt;/a&gt;, &lt;a href="https://twitter.com/michrogowski" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; account and in &lt;a href="https://dev.to/michalrogowski"&gt;dev.to&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For sure I still have to improve some UI issues but as something that I was able to do during one weekend because my kid was with his grandparents I think it's worth it, and it doesn't require a lot of maintenance.&lt;/p&gt;

&lt;p&gt;I found the problem with the template I had to add crossorigin=anonymous to the theme css links to support CORS type deployment where the baseURL may be different than the URL used to see the web page (origin). I've created the fix - PR available &lt;a href="https://github.com/ineesalmeida/almeida-cv/pull/10" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the source code is available &lt;a href="https://github.com/MichalRogowski/rogowski" rel="noopener noreferrer"&gt;here&lt;/a&gt;, if you'd like to buy the app it's &lt;a href="https://apps.apple.com/us/app/exposure-adjustor/id1570960511?mt=12" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>cv</category>
      <category>showdev</category>
      <category>swift</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Videolitic - First Open source Project!</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sat, 08 Feb 2020 20:27:29 +0000</pubDate>
      <link>https://dev.to/michalrogowski/videolitic-first-open-source-project-3baj</link>
      <guid>https://dev.to/michalrogowski/videolitic-first-open-source-project-3baj</guid>
      <description>&lt;p&gt;Hey I was not posting for a while, because I’ve started working on open sourcing my side project called &lt;a href="http://github.com/MichalRogowski/Videolitic" rel="noopener noreferrer"&gt;Videolitic&lt;/a&gt;. I’ve rewritten it to Swift + Combine + SwiftUI from Rx with UIKit so there is a lot of room for improvement - I’ve never done anything in SwiftUI and Combine before.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://github.com/MichalRogowski/Videolitic" rel="noopener noreferrer"&gt;Videolitic&lt;/a&gt;. is an on-device video analysis framework. I am tracking each person from the video and detect his or her age, emotions and ethnicity, I am also creating transcript of the video. All results are combined and time-based.&lt;/p&gt;

&lt;p&gt;This is how it works!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4alik23jtj3ei0rzjwrb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4alik23jtj3ei0rzjwrb.gif" alt="Example" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My main goal is to create better open source models build on top of Vision which can detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Age&lt;/li&gt;
&lt;li&gt;Gender&lt;/li&gt;
&lt;li&gt;Ethnicity&lt;/li&gt;
&lt;li&gt;Emotions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I wasn't able to OpenSource models which was trained on better datasets &lt;/p&gt;

&lt;p&gt;The project is only library - I’ve added some UI just to present the results. There is a lot of Core ML + Vision + Create ML based on transfer learning. &lt;/p&gt;

&lt;p&gt;I also integrated for the first time &lt;a href="https://travis-ci.org" rel="noopener noreferrer"&gt;Travis-CI&lt;/a&gt; and it's GREAT! &lt;/p&gt;

&lt;p&gt;I will create tutorial how to integrate Tavis-CI with the open source GitHub project and some articles with most interesting snippets!&lt;/p&gt;

&lt;p&gt;Please checkout &lt;a href="http://github.com/MichalRogowski/Videolitic" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;  and contribute!&lt;/p&gt;

&lt;p&gt;BTW! If you like my articles please follow me on  &lt;a href="https://twitter.com/michrogowski" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;  Thanks!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>swift</category>
      <category>machinelearning</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Startup idea failed - what’s next?</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sat, 16 Nov 2019 14:22:51 +0000</pubDate>
      <link>https://dev.to/michalrogowski/startup-idea-failed-what-s-next-1j2i</link>
      <guid>https://dev.to/michalrogowski/startup-idea-failed-what-s-next-1j2i</guid>
      <description>&lt;p&gt;1 year ago I’ve started working on a startup idea. I’ve created a pitch deck with market research and an MVP app to prove it works.&lt;/p&gt;

&lt;p&gt;I thought the idea was good so I tried to find a founding. I had really advanced talks with one investor, we were really close to sign a contract, but then Google I/O happened. Investor got scared because he thought that they may be working on similar thing and may be our competitors. I do not agree with him but somehow it got me really bumped down, and I didn’t have energy to start looking for investor once again. So it was on my hard drive for last 6 months getting dusted.&lt;/p&gt;

&lt;p&gt;Now I see two ways how I can proceed:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open source the project&lt;/li&gt;
&lt;li&gt;Try to find an investor&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Personally I’m more convinced to make it open source but maybe you have any other ideas? What are your thoughts on this? Maybe you were in similar situation?&lt;/p&gt;

&lt;p&gt;Thanks! &lt;/p&gt;

&lt;p&gt;P.S. Sorry for not writing for last 2 weeks I had last minute trip to Los Angeles 🏀. I will try to write articles regularly again :)&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>startup</category>
      <category>sideprojects</category>
    </item>
    <item>
      <title>Why sign-in with apple may take you more than 5 minutes and how it works?</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sun, 20 Oct 2019 19:39:49 +0000</pubDate>
      <link>https://dev.to/michalrogowski/why-sign-in-with-apple-may-take-you-more-than-5-minutes-and-how-it-works-55p6</link>
      <guid>https://dev.to/michalrogowski/why-sign-in-with-apple-may-take-you-more-than-5-minutes-and-how-it-works-55p6</guid>
      <description>&lt;p&gt;I saw a lot of articles why Sign In With Apple (SIWA) is - great, easy etc. Only few of them were showing how difficult it may be and this is one of those. I will list all articles that I found about other problems at the end of the article. I described it from iOS perspective.&lt;/p&gt;

&lt;p&gt;BTW! If you like my articles please follow me on &lt;a href="https://twitter.com/michrogowski" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;  Thanks!&lt;/p&gt;

&lt;h2&gt;
  
  
  Sign In With Apple 🍏 (SIWA)
&lt;/h2&gt;

&lt;p&gt;UML diagram below shows register / login flow&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg13z7whrycjkuq09env.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flg13z7whrycjkuq09env.jpg" alt="SIWA-UML" width="572" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SIWA button register / login&lt;/strong&gt; - Most important part of request is scope. For test purposes I’ve added email and full name to scope. When pressing button for the first time user is able to decide, does he want to use real email, or “fake” which will forward all messages to and from user.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ASAuthorizationAppleIDCredential&lt;/strong&gt; - Apple &lt;a href="https://developer.apple.com/documentation/authenticationservices/asauthorizationappleidcredential" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt;  describes it as &lt;em&gt;A credential that results from a successful Apple ID authentication.&lt;/em&gt; You can also check all fields that are returned. Most important for us are:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;var authorizationCode: Data?&lt;/code&gt; - &lt;em&gt;A short-lived token used by your app for proof of authorization when interacting with the app’s server counterpart.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var identityToken: Data?&lt;/code&gt; - &lt;em&gt;A JSON Web Token (JWT) that securely communicates information about the user to your app.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var user: String&lt;/code&gt; - &lt;em&gt;An identifier associated with the authenticated user.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var fullName: PersonNameComponents?&lt;/code&gt; - &lt;em&gt;The user’s name.&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;var email: String?&lt;/code&gt;- &lt;em&gt;The user’s email address.&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Token authorisation code on the diagram above is &lt;code&gt;authorizationCode&lt;/code&gt; from this response - we have to send it to our API Server. Now our server will be able to use it to get JWT as response from &lt;code&gt;Apple /token&lt;/code&gt; servers.&lt;/p&gt;

&lt;p&gt;To decode JWT (identityToken) use &lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;jwt.io&lt;/a&gt; - all validation and debugging is done on the client side👌. My &lt;em&gt;register&lt;/em&gt; JWT looks like&lt;/p&gt;

&lt;h4&gt;
  
  
  HEADER
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"kid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AIDOPK1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RS256"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  PAYLOAD
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://appleid.apple.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.myapp.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1571516448&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1571515848&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"222222.11111111111111111111111111111111.3334"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"c_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9C1Y7-lPwAXGTrrAbciP1T"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hap41ok9pl@privaterelay.appleid.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"email_verified"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"is_private_email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"true"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"auth_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1571515848&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same JWT will be provided to API Server in step 5 but with different timestamps and &lt;em&gt;hash&lt;/em&gt; key and value. &lt;em&gt;sub&lt;/em&gt; is my user id associated with this application, &lt;em&gt;aud&lt;/em&gt; is bundle of the application. &lt;em&gt;hash&lt;/em&gt;, &lt;em&gt;kid&lt;/em&gt; and &lt;em&gt;alg&lt;/em&gt; are needed to confirm that this JWT was created by apple, and confirm it with Apple &lt;a href="https://appleid.apple.com/auth/keys" rel="noopener noreferrer"&gt;public key&lt;/a&gt; it will be done in step 6 by API server. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Register / Login&lt;/strong&gt; - We are sending our &lt;code&gt;authorizationCode&lt;/code&gt; as part of our request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/token&lt;/strong&gt; - thanks to &lt;code&gt;authorizationCode&lt;/code&gt; API Server is able to send &lt;a href="https://appleid.apple.com/auth/token" rel="noopener noreferrer"&gt;/token&lt;/a&gt; request with parameters:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;grant_type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"authorization_code"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;code:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"this is authorizationCode"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;client_id:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"bundle id same value as in “aud” in” JWT above"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;client_secret:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"client secret generated for this app"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TokenResponse&lt;/strong&gt; - response for &lt;em&gt;/token&lt;/em&gt; is
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"access_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a5a45fnksdnfk83jflkasfksd98c29fdf1.1.pfsmo.bfd324145555r15"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"token_type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Bearer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"expires_in"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"refresh_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"r7999999999d0485b85a0d6124124140.1.pfsmo.YFFFFFsadazJYjzw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id_token"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT token"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Put your &lt;code&gt;id_token&lt;/code&gt; again to &lt;a href="https://jwt.io" rel="noopener noreferrer"&gt;jwt.io&lt;/a&gt;  and decode - user values are same as in JWT from &lt;code&gt;ASAuthorizationAppleIDCredential&lt;/code&gt;- things that are different are described above.  We can notice that there is no full name returned by the JWT, so we have to pass it from app. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Register / login user&lt;/strong&gt; - server needs to confirm with Apple &lt;a href="https://appleid.apple.com/auth/keys" rel="noopener noreferrer"&gt;public key&lt;/a&gt;  that JWT was created by them, and not injected in any way. Now we can create our user we have verified &lt;em&gt;email&lt;/em&gt;, &lt;em&gt;userID&lt;/em&gt; so everything we need.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Establish user session&lt;/strong&gt; - response returns our new user with accessToken and refreshToken.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🆒 so where is the problem?
&lt;/h2&gt;

&lt;p&gt;As you may noticed I described register path, with register JWT but how does login JWT looks like? &lt;/p&gt;

&lt;h4&gt;
  
  
  PAYLOAD STEP 5)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iss"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://appleid.apple.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"aud"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"com.myapp.app"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1571516802&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1571516202&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"222222.11111111111111111111111111111111.3334"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"at_hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ArC1Y7-lPwAXGTrrAbciP1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"auth_time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1571516173&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;em&gt;Ok so where is the email?&lt;/em&gt;
&lt;/h3&gt;

&lt;p&gt;This is our problem, there is no &lt;em&gt;email&lt;/em&gt; key in login flow. That means your API Service not only have to implement Apple version of OpenID Connect - main difference for us is no &lt;a href="https://connect2id.com/products/server/docs/api/userinfo" rel="noopener noreferrer"&gt;/userinfo&lt;/a&gt; endpoint. It’s not OpenID Connect compliant, you can check &lt;a href="https://bitbucket.org/openid/connect/src/default/How-Sign-in-with-Apple-differs-from-OpenID-Connect.md" rel="noopener noreferrer"&gt;here&lt;/a&gt; how it differs. If you are using email to &lt;em&gt;authenticate&lt;/em&gt; a user, you may have a problem. Email shouldn’t be mandatory in your system and not only because you may have problem with SIWA, but if you are supporting other identity providers like Facebook, how do you behave if someone has created an account with his/her phone number? &lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Why Sign In With Apple may be problematic? This article was published at 20th of October 2019 - and for that day apple wasn’t OpenID Connect compliant.  Email was only returned once during registration flow, if your API Service needs &lt;em&gt;email&lt;/em&gt; to authenticate user you got a problem. Is it bad? I don’t think so - email shouldn’t be mandatory, Facebook may not return email as well if someone has created account using phone number. If you have to migrate start it now because &lt;em&gt;Apple Requiring New Apps and App Updates to Be Built With iOS 13 SDK Starting in April 2020&lt;/em&gt; so the clock is ticking. &lt;/p&gt;

&lt;p&gt;List of helpful articles:&lt;br&gt;
&lt;a href="https://developer.okta.com/blog/2019/06/04/what-the-heck-is-sign-in-with-apple" rel="noopener noreferrer"&gt;What the Heck is Sign In with Apple? | Okta Developer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://blog.curtisherbert.com/so-theyve-signed-in-with-apple-now-what/" rel="noopener noreferrer"&gt;So They’ve Signed in with Apple, Now What? — Curtis Herbert&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/costerad/sign-in-with-apple-implementation-hurdles-761"&gt;“Sign in with Apple” implementation hurdles - DEV Community 👩‍💻👨‍💻&lt;/a&gt; by @costerad&lt;br&gt;
&lt;a href="https://auth0.com/blog/learn-how-to-implement-sign-in-with-apple-easily/?utm_source=dev&amp;amp;utm_medium=sc&amp;amp;utm_campaign=siwa_ga" rel="noopener noreferrer"&gt;How to Add Sign in with Apple to iOS Apps - Getting Started Guide&lt;/a&gt; by @auth0&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>oauth</category>
      <category>security</category>
      <category>identitymanagement</category>
    </item>
    <item>
      <title>Painless “translations” for Mobile Developers</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sun, 13 Oct 2019 18:40:31 +0000</pubDate>
      <link>https://dev.to/michalrogowski/painless-translations-for-mobile-developers-5ea</link>
      <guid>https://dev.to/michalrogowski/painless-translations-for-mobile-developers-5ea</guid>
      <description>&lt;p&gt;Hey! If you like my articles please follow me on &lt;a href="https://twitter.com/michrogowski" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;  Thanks!&lt;/p&gt;

&lt;h2&gt;
  
  
  Translation vs Localisation
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Translation&lt;/strong&gt; - the process of rendering one text to another, for example Polish to English - “ciasto” -&amp;gt; “cake”&lt;br&gt;
&lt;strong&gt;Localisation&lt;/strong&gt; - This is more thorough process, it addresses cultural expectations, for example date format UK - Day-Month-Year -&amp;gt; US - Month-Day-Year.&lt;/p&gt;
&lt;h2&gt;
  
  
  Plurals - cardinal type 😱
&lt;/h2&gt;

&lt;p&gt;We can look at English (en_GB)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;month&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;months&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Easy right, but what about other languages - polish: (pl_PL)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;miesiąc&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;miesiące&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="n"&gt;miesięcy&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="mi"&gt;22&lt;/span&gt; &lt;span class="n"&gt;miesiące&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In polish we have 3 possible plural forms of &lt;code&gt;month&lt;/code&gt;. How can we manage it in our code? Android and iOS store translations differently, they are using different format &lt;code&gt;.xml&lt;/code&gt; vs &lt;code&gt;.strings&lt;/code&gt; - singulars and &lt;code&gt;.stringsdict&lt;/code&gt; - plurals. Nonetheless they have common plural categories:&lt;br&gt;
&lt;strong&gt;Zero, one, two, few, many, other&lt;/strong&gt; — You can see rules for the categories for each language at &lt;a href="http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html" rel="noopener noreferrer"&gt;CLDR Language Plural Rules.&lt;/a&gt;. &lt;a href="https://github.com/unicode-org/cldr/blob/2dd06669d833823e26872f249aa304bc9d9d2a90/common/supplemental/plurals.xml" rel="noopener noreferrer"&gt;Here&lt;/a&gt; is xml format you can use if you would like to create your own parsing script.&lt;/p&gt;

&lt;p&gt;Android plural example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;plurals&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;“you_have_x_points”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;quantity=&lt;/span&gt;&lt;span class="s"&gt;“one”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;You have %s point&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;item&lt;/span&gt; &lt;span class="na"&gt;quantity=&lt;/span&gt;&lt;span class="s"&gt;“other”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;You have %s points&lt;span class="nt"&gt;&amp;lt;/item&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/plurals&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;iOS Plural example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=“1.0” encoding=“UTF-8”?&amp;gt;&lt;/span&gt; 
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE plist PUBLIC “-//Apple//DTD PLIST 1.0//EN” “http://www.apple.com/DTDs/PropertyList-1.0.dtd”&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;plist&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;“1.0”&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;Older than %d month(s)&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSStringLocalizedFormatKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;Older than %#@months@&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;months&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;dict&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSStringFormatSpecTypeKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;NSStringPluralRuleType&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;NSStringFormatValueTypeKey&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;d&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;one&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;%d month&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;other&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt; 
            &lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;%d months&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt; 
        &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt; 
    &lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dict&amp;gt;&lt;/span&gt; 
&lt;span class="nt"&gt;&amp;lt;/plist&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Android xml is very straightforward but if you want to understand more details about .stringdict structure just read this apple &lt;a href="https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/StringsdictFileFormat/StringsdictFileFormat.html" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;. If you have any questions I’ll be happy to help :)&lt;/p&gt;

&lt;h2&gt;
  
  
  How to translate your app
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Native way
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Android&lt;/strong&gt; you can use &lt;a href="https://support.google.com/l10n/answer/6359997" rel="noopener noreferrer"&gt;Google Play App Translation service&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;iOS&lt;/strong&gt; I don’t think there is native translation service if I’m wrong please update me! :) &lt;/p&gt;

&lt;h3&gt;
  
  
  Do It Yourself
&lt;/h3&gt;

&lt;p&gt;You can manually manage translations, in Xcode you can export/import &lt;a href="https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LocalizingYourApp/LocalizingYourApp.html" rel="noopener noreferrer"&gt;.xliff&lt;/a&gt; file and send it to translators. Android Studio has &lt;a href="http://tools.android.com/recent/androidstudio087released" rel="noopener noreferrer"&gt;Android Studio Translation Editor&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3rd party Translation Service
&lt;/h3&gt;

&lt;p&gt;For everyone this term may mean something else, but in my opinion Translation Service should provide at least few functionalities for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Divide translations per application - different “folders”&lt;/li&gt;
&lt;li&gt;Import export functionality&lt;/li&gt;
&lt;li&gt;Providing API or/and scripts you can use to make translations part of your CI / CD processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a lot of paid solutions and few open source - if needed you can create something yourself which would better fit your needs. &lt;/p&gt;

&lt;p&gt;In my opinion the best part for developers is API or script that you can use to automate whole process. I will describe example flow which you can implement in your teams - it was created by my colleagues and me.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create list of supported languages.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Send strings that should be translated from apps to Translation Service&lt;/strong&gt; - it should be automated. Our CI every time after merge is checking does this string already exists in our Translation Service database, if not it will create new record to be translated for this app. Script has to know where origin (usually English) strings are, and how those are stored to get value, context and check is it plural.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Notify translators&lt;/strong&gt; - if you have internal translators you can just setup web hook to send slack message that new strings are waiting to be translated, or notify external agency and export all files to translate unless you can give them access to your translation service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Receive translated string&lt;/strong&gt; - same as sending it’s done by CI and internal script, while fetching translations for each string it automatically generate new files for iOS (.strings, .stringdict) and android (.xml)  to always have most recent translations in apps. When git diff is not empty, it automatically creates new pull request! We could have just add new commit but we decided that new pull request gives us more control over it - it has to be manually merged.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Localisation
&lt;/h2&gt;

&lt;p&gt;Remember to always use correct locale in your app for things like date format, metric system, currency code or symbol etc. It’s very important and may be very misleading for your users if it’s done incorrectly. Most of use cases are supported natively by both platforms so don’t write it on your own just use ready native solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep in mind
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;If your company is working with external translators remember to educate them! Educate about parameters, escaping, special characters etc. If you will not educate translators how they should translate it, you will spend a lot of time fixing translations to make them work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go through all translations, you can UI Test or Unit test them. Check that there are no crashes, that in string with two parameters translators didn’t switch them, and now you’re sending bad parameters types, for example Int instead of string. Just double check it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fallback - this is mostly business decision, but I would not recommend any complex fallback mechanism. I’m always trying to use English version if translated version doesn’t exists, it pretty secure because usually  people immediately would notice it’s just not translated - falling back from Mexican Spanish to standard Spanish may be risky and just confuse your user.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remember to also translate and localise assets, store strings like: “what’s new” etc.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check your interface for RTL (right to left) languages, make sure it works and looks good.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;It’s very important to do it correctly, it opens new markets for your app and really change user experience. On the other hand if done incorrectly it may be misleading.&lt;/p&gt;

&lt;p&gt;If you have any question just add a comment or message me directly on social media 👾&lt;/p&gt;

</description>
      <category>translations</category>
      <category>ios</category>
      <category>android</category>
      <category>mobile</category>
    </item>
    <item>
      <title>Grow as a Professional Software Developer</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Fri, 04 Oct 2019 17:24:20 +0000</pubDate>
      <link>https://dev.to/michalrogowski/grow-as-a-professional-software-developer-1b85</link>
      <guid>https://dev.to/michalrogowski/grow-as-a-professional-software-developer-1b85</guid>
      <description>&lt;p&gt;When I stared my journey as an iOS Developer, it was super easy to find things to learn - to be honest it was hard to find things I knew and I felt confident about. Nonetheless after a year or two there came a dangerous moment of &lt;em&gt;routine&lt;/em&gt;: my level of knowledge let me do my job and give a phoney 😱 feeling of being a professional.&lt;/p&gt;

&lt;p&gt;Luckily for me a wake-up call came when I was talking with some other iOS Developer and he started to talk about things that I should be familiar with - but I didn’t have a clue what he was talking about. Since then I’m trying to always be aware when there is too much routine in my daily workflow, and now I know how to grow on top of that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find your weaknesses
&lt;/h2&gt;

&lt;p&gt;In my opinion, it doesn’t matter what’s your current experience or where you want to be in 5 years, some people naturally see only good sides of themselves while others suffer from &lt;a href="https://www.youtube.com/watch?v=yT3xZQQHK4Y" rel="noopener noreferrer"&gt;Imposter Syndrome&lt;/a&gt;. That’s why people have problems deciding what parts of professional life they should improve - the way we see ourselves may be completely different than the perception of us other people have. If there is no feedback culture in your workplace you can ask other coworkers for help in few different ways:&lt;/p&gt;

&lt;h3&gt;
  
  
  360 Feedback
&lt;/h3&gt;

&lt;p&gt;If you aren’t familiar with this term, it’s a process in which you can receive anonymous feedback from people that you work with. Maybe it’s a common practise at your workplace, and maybe you have to initiate it, but it’s worth it - trust me. In our team, I’ve created anonymous google docs with 7 sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Communication&lt;/li&gt;
&lt;li&gt;Problem-solving and decision-making&lt;/li&gt;
&lt;li&gt;Organisation and time management&lt;/li&gt;
&lt;li&gt;Interpersonal skills &lt;/li&gt;
&lt;li&gt;Continuous improvement&lt;/li&gt;
&lt;li&gt;Motivation&lt;/li&gt;
&lt;li&gt;Team working&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://forms.gle/CfUwsmFW421Q2uM79" rel="noopener noreferrer"&gt;Here&lt;/a&gt; it is. Every team member had his own copy of this form. When everybody received feedback from everyone who was involved, I shared results with my teammates. You can export results to csv and add some rule to make and highlight weighted results under X and over Y. This is how you can recognise your gaps and strengths. I like to split results in two types: programming and communication -  to work on both simultaneously. Communication skills are as important as programming skills, you are part of the team and you have to know how to build good and healthy relationships, because internal conflicts may destroy even the best project.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhny0d2fv5a7mqpzjmnfx.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhny0d2fv5a7mqpzjmnfx.gif" alt="TeamMates" width="300" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Annual review
&lt;/h3&gt;

&lt;p&gt;Usually annual reviews are twice a year and are part of company’s policies, but if it’s not your case, just ask your line manager or any other teammate for a meeting, describe what do you expect from him/her.  As a line manager I always prepare myself before a meeting and stick to the agenda:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Receive a feedback about yourself, and workplace.&lt;br&gt;
The most important rule during this part of talk is to &lt;em&gt;Avoid Defensiveness&lt;/em&gt;, you may be surprised how easy it is to discourage someone and stop getting honest feedback. Even when you do not agree with your subordinate’s opinion, just hold your tongue, and try to understand his/her point of view. You can always respond later after analyzing it from different angles. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give a feedback&lt;br&gt;
Try to prepare yourself as good as possible, do not make personal assumptions and stick to facts. Do not say stuff like “you are bored on our sprint planning meetings” - that’s just your perspective, someone can easily disagree and you can’t prove it. Phrase it like this “when you are going through your phone during our sprint planning meetings, it looks unprofessional”. First give an example of behaviour which is objective, and then state the result, without judging. You should give positive feedback as well, it’s even better to only give positive feedback at the beginning - you can learn how to construct a correct sentence with behaviour-&amp;gt;result approach. I do not like sandwich technique, people may notice it and ignore positive feedback. It may seem like you’ve only said praises because you had to, they would focus only on the negative parts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Future&lt;br&gt;
Now it’s time to focus on what we can achieve together in the next few months. It may be related to the processes, or someone’s grow - create new personal goals which will be verified on a next annual review. I like the idea I heard from my line manager: go through some dream job offers, and point the weaknesses (“Why I’m not feeling confident enough to apply for that job?”), and then change those to goals. This way your goals are pushing you in your career.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Other
&lt;/h3&gt;

&lt;p&gt;The usual day to day activities that may keep you up to date. You can be subscribed to some weekly newsletters with best articles about topics you are interested in or watch some videos on Pluralsight and YouTube.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to keep being motivated?
&lt;/h2&gt;

&lt;p&gt;This is as important as creating goals for yourself, I will try to provide some answers in my next article.&lt;/p&gt;

&lt;p&gt;P.S. Growing is good, but everyone has their limits, remember to not overstrain yourself.&lt;/p&gt;

&lt;p&gt;Thanks! If you like it please follow me on Twitter.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>management</category>
      <category>career</category>
      <category>advice</category>
    </item>
    <item>
      <title>Swift Memory Management and Performance</title>
      <dc:creator>Michal Rogowski</dc:creator>
      <pubDate>Sun, 29 Sep 2019 20:02:14 +0000</pubDate>
      <link>https://dev.to/michalrogowski/memory-management-swift-266b</link>
      <guid>https://dev.to/michalrogowski/memory-management-swift-266b</guid>
      <description>&lt;p&gt;As part of recruitment processes one of the most common questions is: “What is the difference between struct and class”, we usually can hear that &lt;code&gt;class&lt;/code&gt; is copied by reference and &lt;code&gt;struct&lt;/code&gt; by value. But what does it even mean? Let’s start with general introduction to Memory Management&lt;/p&gt;

&lt;h2&gt;
  
  
  What is memory?
&lt;/h2&gt;

&lt;p&gt;We can try to imagine memory as array of cells, each cell contains an information. Typically size of this information is one byte (e.g. bin: 01100101, hex: 0x65), each cell is associated with address which allows us to write or read value from this particular address. Assuming our app is using 20 Megabytes, we have to use 20 000 000 cells, and each cell contains 8 bits.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax03do34dqn02260mlqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fax03do34dqn02260mlqi.png" alt="Memory visualisation" width="754" height="1338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the picture above, on the left there is the address and on the right is the value associated with this address. But what happens when value we want to store is bigger than size of one cell?&lt;/p&gt;

&lt;h3&gt;
  
  
  Little-endian vs Big-endian
&lt;/h3&gt;

&lt;p&gt;The purpose of both of those terms is to decide in which order bytes are stored in memory. Big-endian stores most significant value at the lowest storage address, little-endian is doing the opposite. Let’s take a look at this examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;decimalValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Int16&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20306&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The binary value of this Integer is &lt;code&gt;100111101010010&lt;/code&gt;&lt;br&gt;
So let’s split those bits by size of our cells which is 1 byte.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;firstPart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;01001111&lt;/span&gt;
&lt;span class="n"&gt;secondPart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;01010010&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need two cells, to allocate this value in memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Big-endian
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr61p1fy55icis72gd0h7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr61p1fy55icis72gd0h7.png" alt="Alt Text" width="754" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Little-endian
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz9jau9lo1erhmb32gzn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz9jau9lo1erhmb32gzn.png" alt="Alt Text" width="754" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see Big-endian seems more natural for people who read left to right but the problem is with increasing a number, when number growths in binary system, numbers are added to the left side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1111&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;
&lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0001&lt;/span&gt; &lt;span class="mi"&gt;1111&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;31&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if our number growths in memory, in Big-endian notation we would have to rewrite all addresses values, in Little-endian we would just append it at the end.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;decimalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1111&lt;/span&gt; &lt;span class="mi"&gt;1111&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;decimalValue&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="nb"&gt;bin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0000&lt;/span&gt; &lt;span class="mi"&gt;0001&lt;/span&gt; &lt;span class="mi"&gt;1111&lt;/span&gt; &lt;span class="mi"&gt;1111&lt;/span&gt; &lt;span class="n"&gt;dec&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;511&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;1)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcwaiirulhpmiyxacsyp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcwaiirulhpmiyxacsyp.png" alt="Alt Text" width="754" height="94"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Big-endian
&lt;/h3&gt;

&lt;p&gt;2)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2kprt07f5rw2q72dc7u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn2kprt07f5rw2q72dc7u.png" alt="Alt Text" width="752" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see the value from memory address &lt;code&gt;0x0000000112856f55&lt;/code&gt; was rewritten to &lt;code&gt;0x0000000112856f56&lt;/code&gt; &lt;/p&gt;
&lt;h3&gt;
  
  
  Little-endian
&lt;/h3&gt;

&lt;p&gt;2)&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flcfwoogappm53685kdg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flcfwoogappm53685kdg6.png" alt="Alt Text" width="752" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;New value was assigned at the end (new memory address)&lt;/p&gt;
&lt;h1&gt;
  
  
  Why do I care? Swift vs bits
&lt;/h1&gt;

&lt;p&gt;You will seldom have to know the difference between Big-endian and Little-endian, or even understand how memory looks like. But if you’d like to grow as a developer and understand how things work under the hood - continue reading.&lt;/p&gt;
&lt;h2&gt;
  
  
  Xcode and Memory Viewer
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;helloWorld&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="kt"&gt;Hello&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;World&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="nf"&gt;withUnsafePointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;helloWorld&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;helloWorld&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s put a breakpoint on print, when the breakpoints fires, we can activate memory viewer in Xcode! (Yes it exists ❤️) , when execution is paused on breakpoint just go to Debug -&amp;gt; Debug Workflow -&amp;gt; View Memory.&lt;/p&gt;

&lt;p&gt;In our console we can see printed hexadecimal memory address, thanks to it we know address of memory we want to show in our viewer, just paste address and press enter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9ubhl0zgufo6bi6f26d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff9ubhl0zgufo6bi6f26d.png" alt="Memory Viewer" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
Now we can check how is it stored on my Mac! &lt;br&gt;
In the left column we can see the addresses of the first cells in each row written in hexadecimal, we can change it to decimal by tapping on left column.&lt;/p&gt;

&lt;p&gt;In the center there are cells with their values. Each cell value is one Byte, so value stored under address 0x100002060 is 48 hexadecimal, which means character H, because this string is encoded in UTF-8 whose representation is the same as ASCII for Latin alphabet, here is simple &lt;a href="https://upload.wikimedia.org/wikipedia/commons/thumb/1/1b/ASCII-Table-wide.svg/2880px-ASCII-Table-wide.svg.png" rel="noopener noreferrer"&gt;Ascii table&lt;/a&gt; - representing values associated with characters, if you’d like to know more about ascii, encoding and decoding please let me know!&lt;/p&gt;

&lt;p&gt;In the right column we can see preview of memory &lt;code&gt;Hello, World!í&lt;/code&gt; this is our value displayed in preview.&lt;/p&gt;

&lt;p&gt;There are few questions that comes to mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Is it Big-endian or Little-endian?&lt;br&gt;
It is Little-endian, just replace the string value with 511 from example above and compare results, value is also hexadecimal, we would expect that value is &lt;code&gt;FF 01&lt;/code&gt; It’s hard to debug it on characters, because ascii strings are &lt;code&gt;arrays&lt;/code&gt; of single byte values, that’s why endianness does not affect the order.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is this special character, and why is it prefixed with 2 bytes of 0x00?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;My system is 64 bits so size of this string is not 13 bytes, even if it only contains 13 characters, it’s 2*8 bytes, last byte has a special value to indicate end of string.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can easily check size of this string by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;MemoryLayout&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;ofValue&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;helloWorld&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;//prints 16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Copy by reference
&lt;/h2&gt;

&lt;p&gt;Look at this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;//  Created by Michał Rogowski on 27/09/2019.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;

&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;TestClassByReference&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test2&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test3&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test4&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test5&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value6&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test6&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;

    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UnsafeMutableRawPointer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kt"&gt;Unmanaged&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;passUnretained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toOpaque&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;testObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;TestClassByReference&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;copyTestObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;testObject&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;testObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;copyTestObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copyTestObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;copyTestObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;copyTestObject&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copyTestObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We should add two break points, on &lt;code&gt;copyTestObject.value1 = “change”&lt;/code&gt; and on last print. &lt;/p&gt;

&lt;p&gt;On first breakpoint we can notice that two addresses are the same, so jump to memory viewer!&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz480rz06bj3fx67dz1mr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz480rz06bj3fx67dz1mr.png" alt="Memory View reference.1" width="800" height="410"&gt;&lt;/a&gt;&lt;br&gt;
On the right column, our properties values are visible (test, test2, test3 etc.), now we can continue program execution, address of variables did not change, so we can move to memory viewer again.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41q3n5qmpyfcwjsrx0cw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F41q3n5qmpyfcwjsrx0cw.png" alt="Memory View reference.2" width="800" height="410"&gt;&lt;/a&gt;&lt;br&gt;
Value &lt;code&gt;test&lt;/code&gt; was changed and the memory reflects that by presenting a new string value in a place of previous one! Both instances point to same address - share a single copy of data. This explains the first category of instances types supported by Swift which is Reference Type.&lt;/p&gt;
&lt;h2&gt;
  
  
  Copy-on-Write
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;//  Created by Michał Rogowski on 27/09/2019.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;

&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;Array&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="kt"&gt;Element&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;UnsafePointer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;withUnsafeBufferPointer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;baseAddress&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;testObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test2&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test3&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test4&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test5&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test6&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;copyTestObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;testObject&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;testObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="nv"&gt;copyTestObject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copyTestObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;copyTestObject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;change&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;copyTestObject&lt;/span&gt; &lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="n"&gt;after&lt;/span&gt; &lt;span class="nv"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;copyTestObject&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;testObject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now we can debug it step by step, compare the addresses of both arrays before changing value in our copy. Addresses are the same, but what happens after our change.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x59t8cakml4mopu63a9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2x59t8cakml4mopu63a9.png" alt="Copy on write before" width="800" height="410"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcutz3cfey4vlspj49kie.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcutz3cfey4vlspj49kie.png" alt="Copy on write after" width="800" height="410"&gt;&lt;/a&gt;&lt;br&gt;
Address was changed and whole array was rewritten.&lt;br&gt;
We have to notice that Copy-on-Write is only implemented for certain types, for example Arrays. If you’d like to use it for your structures-to optimise memory, you would have to create value wrapper, as described by &lt;a href="https://github.com/apple/swift/blob/master/docs/OptimizationTips.rst#advice-use-copy-on-write-semantics-for-large-values" rel="noopener noreferrer"&gt;Apple Here&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Copy by value
&lt;/h2&gt;

&lt;p&gt;Second category that is supported by Swift are Value Types. That means each instance keeps unique memory location for its data. Take a look&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;//  Created by Michał Rogowski on 27/09/2019.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;

&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;MyStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;firstStruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;MyStruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;copyStruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;firstStruct&lt;/span&gt;

&lt;span class="nf"&gt;withUnsafePointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;firstStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;//print 0x00000001000040b0&lt;/span&gt;
&lt;span class="nf"&gt;withUnsafePointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;copyStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;//print 0x00000001000040b8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both properties have different addresses since the begging, in this case the memory addresses are allocated by 8 Bytes (Because of 64-bit system).&lt;br&gt;
As you can read in Swift Documentation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// A signed integer value type.&lt;/span&gt;
&lt;span class="c1"&gt;///&lt;/span&gt;
&lt;span class="c1"&gt;/// On 32-bit platforms, `Int` is the same size as `Int32`, and&lt;/span&gt;
&lt;span class="c1"&gt;/// on 64-bit platforms, `Int` is the same size as `Int64`.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why should we waste 8 bytes for variable that needs only 1 byte? What would happen if we change default Int in our structure to &lt;code&gt;Int8&lt;/code&gt;? Change declaration of &lt;code&gt;Int&lt;/code&gt; in MyStruct&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;MyStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Int8&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And those are allocated addresses for this two structs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="mh"&gt;0x0000000100004088&lt;/span&gt;
&lt;span class="mh"&gt;0x0000000100004089&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the difference between addresses is only 1 Byte. We were able to free 7 bytes of memory per instance of &lt;code&gt;MyStruct&lt;/code&gt; just by changing declaration to &lt;code&gt;Int8&lt;/code&gt;, on the other hand you have to be careful to choose correct size because &lt;em&gt;integer overflow&lt;/em&gt; may cause unintended behaviour.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Value Types&lt;/em&gt; are usually defines as a &lt;code&gt;struct&lt;/code&gt;, &lt;code&gt;enum&lt;/code&gt;, or &lt;code&gt;tuple&lt;/code&gt; (&lt;code&gt;Int&lt;/code&gt; in Swift is also a Struct).     &lt;/p&gt;

&lt;h2&gt;
  
  
  In-Out Parameters
&lt;/h2&gt;

&lt;p&gt;We can think about memory efficiency not only by allocating one Byte integers instead of eight Byte, but there is also &lt;code&gt;In-Out Parameter&lt;/code&gt;&lt;br&gt;
As Swift documentations states &lt;a href="https://docs.swift.org/swift-book/ReferenceManual/Declarations.html#ID545" rel="noopener noreferrer"&gt;Here&lt;/a&gt;:&lt;br&gt;
&lt;em&gt;In-out parameters are passed as follows:&lt;/em&gt;&lt;br&gt;
&lt;em&gt;1. When the function is called, the value of the argument is copied.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;2. In the body of the function, the copy is modified.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;3. When the function returns, the copy’s value is assigned to the original argument.&lt;/em&gt;&lt;br&gt;
&lt;em&gt;This behaviour is known as copy-in copy-out or call by value result.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;struct&lt;/span&gt; &lt;span class="kt"&gt;InoutStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;

    &lt;span class="k"&gt;mutating&lt;/span&gt; &lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;withUnsafePointer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;“&lt;/span&gt;&lt;span class="n"&gt;address&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;\(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;addTestInout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;inoutStruct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;inout&lt;/span&gt; &lt;span class="kt"&gt;InoutStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;inoutStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="n"&gt;inoutStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;addTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="nv"&gt;normalStruct&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;InoutStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;InoutStruct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;inoutStructCopy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;normalStruct&lt;/span&gt;
    &lt;span class="n"&gt;inoutStructCopy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="err"&gt;“&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt;&lt;span class="err"&gt;”&lt;/span&gt;
    &lt;span class="n"&gt;inoutStructCopy&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;inoutStructCopy&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;inoutStruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;InoutStruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;normalStruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;InoutStruct&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;inoutStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//0x0000000100003090&lt;/span&gt;
&lt;span class="n"&gt;normalStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//0x00000001000030a0&lt;/span&gt;

&lt;span class="nf"&gt;addTestInout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;inoutStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//0x0000000100003090&lt;/span&gt;
&lt;span class="n"&gt;normalStruct&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;addTest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;normalStruct&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;//0x00007ffeefbff270&lt;/span&gt;

&lt;span class="n"&gt;inoutStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//0x0000000100003090&lt;/span&gt;
&lt;span class="n"&gt;normalStruct&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;printAddress&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;//0x00000001000030a0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We’ve done the “same” operation twice to separate instances of &lt;code&gt;InoutStruct&lt;/code&gt;, if you go through Memory View, you can check that, in the memory we have 3 instances of &lt;code&gt;InoutStruct&lt;/code&gt;. One of those is variable inoutStructCopy. It’s clear now that, &lt;code&gt;inout&lt;/code&gt; parameter is memory efficient if we want to change instance that is &lt;code&gt;Value Type&lt;/code&gt; in function. There is no extra rewrite, which means you wan’t have to waste time and memory when changing really big &lt;code&gt;Value Type&lt;/code&gt; instances.&lt;/p&gt;

&lt;p&gt;Thanks!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>ios</category>
      <category>memory</category>
      <category>computerscience</category>
    </item>
  </channel>
</rss>
