
{
	"version": "https://jsonfeed.org/version/1.1",
	"title": "Lord Codes » Feed",
	"language": "en_GB",
	"home_page_url": "https://www.lordcodes.com/feed.json",
	"feed_url": "https://www.lordcodes.com/feed.json",
	"description": "Lord Codes blog content on Kotlin and Swift, mainly targeting Android and iOS. Learn about the basics and advanced topics to help you build better apps.",
	"author": {
		"name": "Andrew Lord",
		"url": "https://www.lordcodes.com/about/"
	},
	"items": [		{
			"id": "https://www.lordcodes.com/articles/compose-embed-searchbar-topappbar/",
			"url": "https://www.lordcodes.com/articles/compose-embed-searchbar-topappbar/",
			"title": "Embed a SearchBar into a TopAppBar in Jetpack Compose",
			"content_html": "<p>For many apps, search is a key part of creating a seamless and intuitive user experience. When it comes to building Android UIs with Compose, this can be achieved using the Material 3 <code>SearchBar</code>. The search bar component allows us to build a bar that, when focused, expands into a search view to display suggestions or search results.</p><p>When used as it comes, the <code>SearchBar</code> works nicely by itself and for large screens there is also a <code>DockedSearchBar</code>. Most Android screens, however, include a <code>TopAppBar</code> that has a background colour that changes when content scrolls behind it.</p><p>In this article, we will explore how to build a search experience and then how to embed it seamlessly into a <code>TopAppBar</code>. This allows us to create a polished UI that's perfect for including search into any screen.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/d_W4hk63eV-814.webp 814w\"><img src=\"https://www.lordcodes.com/img/d_W4hk63eV-814.jpeg\" alt=\"SearchBar below the TopAppBar\" title=\"SearchBar below the TopAppBar\" class=\"article-img-medium\" width=\"814\" height=\"438\"></picture></p><h2 id=\"the-problem\" tabindex=\"-1\">The problem</h2><p>As a starting point, we have a screen within our navigation hierarchy showing a list of projects. The projects list includes a <code>TopAppBar</code> containing a navigation icon and title. We would like to be able to search across these projects, using a persistent search bar within the top bar, below the title.</p><p>When we add the search bar below our <code>TopAppBar</code>, it is positioned correctly, however it is visually separate from the top bar.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/r3sxExqCjZ-750.webp 750w\"><img src=\"https://www.lordcodes.com/img/r3sxExqCjZ-750.jpeg\" alt=\"SearchBar below the TopAppBar\" title=\"SearchBar below the TopAppBar visually separated from the top bar\" class=\"article-img-medium\" width=\"750\" height=\"409\"></picture></p><p>There are various changes we need to make so that it appears within the bar:</p><ol><li>Add a surface behind the <code>SearchBar</code> that matches the <code>TopAppBar</code>.</li><li>Match the elevation behaviour, when content scrolls behind the <code>TopAppBar</code>.</li><li>Apply styling when the <code>SearchBar</code> expands into a search view.</li></ol><h2 id=\"building-a-search-bar\" tabindex=\"-1\">Building a search bar</h2><p>Let's start by building our <code>SearchBar</code>.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span>\n<span class=\"token annotation builtin\">@OptIn</span><span class=\"token punctuation\">(</span>ExperimentalMaterial3Api<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">fun</span> <span class=\"token function\">EmbeddedSearchBar</span><span class=\"token punctuation\">(</span>\n    onQueryChange<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>String<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">,</span>\n    isSearchActive<span class=\"token operator\">:</span> Boolean<span class=\"token punctuation\">,</span>\n    onActiveChanged<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>Boolean<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">,</span>\n    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<span class=\"token punctuation\">,</span>\n    onSearch<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>String<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">)</span><span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> searchQuery <span class=\"token keyword\">by</span> rememberSaveable <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span>\n    <span class=\"token comment\">// 1</span>\n    <span class=\"token keyword\">val</span> activeChanged<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>Boolean<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> active <span class=\"token operator\">-></span>\n        searchQuery <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span>\n        <span class=\"token function\">onQueryChange</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span><span class=\"token punctuation\">)</span>\n        <span class=\"token function\">onActiveChanged</span><span class=\"token punctuation\">(</span>active<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">SearchBar</span><span class=\"token punctuation\">(</span>\n        query <span class=\"token operator\">=</span> searchQuery<span class=\"token punctuation\">,</span>\n        <span class=\"token comment\">// 2</span>\n        onQueryChange <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> query <span class=\"token operator\">-></span>\n            searchQuery <span class=\"token operator\">=</span> query\n            <span class=\"token function\">onQueryChange</span><span class=\"token punctuation\">(</span>query<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token comment\">// 3</span>\n        onSearch <span class=\"token operator\">=</span> onSearch<span class=\"token punctuation\">,</span>\n        active <span class=\"token operator\">=</span> isSearchActive<span class=\"token punctuation\">,</span>\n        onActiveChange <span class=\"token operator\">=</span> activeChanged<span class=\"token punctuation\">,</span>\n        <span class=\"token comment\">// 4</span>\n        modifier <span class=\"token operator\">=</span> modifier\n            <span class=\"token punctuation\">.</span><span class=\"token function\">padding</span><span class=\"token punctuation\">(</span>start <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> top <span class=\"token operator\">=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> bottom <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxWidth</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        placeholder <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Search\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        leadingIcon <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>Search<span class=\"token punctuation\">,</span>\n                contentDescription <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n                tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>onSurfaceVariant<span class=\"token punctuation\">,</span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token comment\">// 5</span>\n        colors <span class=\"token operator\">=</span> SearchBarDefaults<span class=\"token punctuation\">.</span><span class=\"token function\">colors</span><span class=\"token punctuation\">(</span>\n            containerColor <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>surfaceContainerLow<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        tonalElevation <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// Search suggestions or results</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><ol><li>When the search bar receives focus it becomes active and expands. At this point we clear the search term and report the active state change via the <code>onActiveChanged</code> function. Note: if we wanted to keep the search term we wouldn't clear it here.</li><li>When the query changes we update the search term state and report the change via the <code>onQueryChange</code> function.</li><li>The IME search triggers <code>onSearch</code>. For now we are updating results whenever the query changes so are simply deactivating the search mode. If we were using a search API request we would perform the search here instead.</li><li>Add our search bar padding, sizing and other modifiers.</li><li>Style the search bar appearance, such as background colour.</li></ol><h2 id=\"position-the-search-bar\" tabindex=\"-1\">Position the search bar</h2><p>The top of the screen is a <code>TopAppBar</code> we have extracted out to <code>ProjectsTopAppBar</code>, which is configured with a back button and title.</p><details><summary><p>Show code for <code>ProjectTopAppBar</code></p></summary><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span>\n<span class=\"token annotation builtin\">@OptIn</span><span class=\"token punctuation\">(</span>ExperimentalMaterial3Api<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">ProjectsTopAppBar</span><span class=\"token punctuation\">(</span>\n    onBackClick<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">,</span>\n    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<span class=\"token punctuation\">,</span>\n    scrollBehavior<span class=\"token operator\">:</span> TopAppBarScrollBehavior<span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">TopAppBar</span><span class=\"token punctuation\">(</span>\n        title <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Projects\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        modifier <span class=\"token operator\">=</span> modifier<span class=\"token punctuation\">,</span>\n        navigationIcon <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">IconButton</span><span class=\"token punctuation\">(</span>onClick <span class=\"token operator\">=</span> onBackClick<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                    imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>AutoMirrored<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>ArrowBack<span class=\"token punctuation\">,</span>\n                    contentDescription <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Back\"</span></span><span class=\"token punctuation\">,</span>\n                <span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        colors <span class=\"token operator\">=</span> TopAppBarDefaults<span class=\"token punctuation\">.</span><span class=\"token function\">topAppBarColors</span><span class=\"token punctuation\">(</span>\n            navigationIconContentColor <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>primary<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        scrollBehavior <span class=\"token operator\">=</span> scrollBehavior<span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre></details><p>When using the Material 3 <code>Scaffold</code> we can use a <code>Column</code> to position the <code>SearchBar</code> below the bar.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">var</span> isSearchActive <span class=\"token keyword\">by</span> rememberSaveable <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span>\n<span class=\"token keyword\">val</span> scrollBehavior <span class=\"token operator\">=</span> TopAppBarDefaults<span class=\"token punctuation\">.</span><span class=\"token function\">pinnedScrollBehavior</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">Scaffold</span><span class=\"token punctuation\">(</span>\n    modifier <span class=\"token operator\">=</span> modifier<span class=\"token punctuation\">,</span>\n    topBar <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n        Column <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">ProjectsTopAppBar</span><span class=\"token punctuation\">(</span>\n                onBackClick <span class=\"token operator\">=</span> onBackClick<span class=\"token punctuation\">,</span>\n                scrollBehaviour <span class=\"token operator\">=</span> scrollBehavior<span class=\"token punctuation\">,</span>\n            <span class=\"token punctuation\">)</span>\n            <span class=\"token function\">EmbeddedSearchBar</span><span class=\"token punctuation\">(</span>\n                onQueryChange <span class=\"token operator\">=</span> onQueryChange<span class=\"token punctuation\">,</span>\n                isSearchActive <span class=\"token operator\">=</span> isSearchActive<span class=\"token punctuation\">,</span>\n                onActiveChanged <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> isSearchActive <span class=\"token operator\">=</span> it <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> contentPadding <span class=\"token operator\">-></span>\n    <span class=\"token comment\">// Search suggestions or results</span>\n<span class=\"token punctuation\">}</span></code></pre><p>We now have a <code>SearchBar</code> showing below our <code>TopAppBar</code>, we next need to add a surface behind it so that it appears visually within the <code>TopAppBar</code>.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/r3sxExqCjZ-750.webp 750w\"><img src=\"https://www.lordcodes.com/img/r3sxExqCjZ-750.jpeg\" alt=\"SearchBar below the TopAppBar\" title=\"SearchBar below the TopAppBar visually separated from the top bar\" class=\"article-img-medium\" width=\"750\" height=\"409\"></picture></p><h2 id=\"surface-behind-the-search-bar\" tabindex=\"-1\">Surface behind the search bar</h2><p>The <code>TopAppBar</code> is built with a surface that adapts its container colour based on the scroll behaviour applied to it. We can create a surface to display behind the <code>SearchBar</code> that uses the same styling.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@OptIn</span><span class=\"token punctuation\">(</span>ExperimentalMaterial3Api<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n<span class=\"token annotation builtin\">@Composable</span>\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">TopAppBarSurface</span><span class=\"token punctuation\">(</span>\n    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<span class=\"token punctuation\">,</span>\n    <span class=\"token comment\">// 1</span>\n    colors<span class=\"token operator\">:</span> TopAppBarColors <span class=\"token operator\">=</span> TopAppBarDefaults<span class=\"token punctuation\">.</span><span class=\"token function\">topAppBarColors</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n    <span class=\"token comment\">// 2</span>\n    scrollBehavior<span class=\"token operator\">:</span> TopAppBarScrollBehavior<span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n    content<span class=\"token operator\">:</span> <span class=\"token annotation builtin\">@Composable</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token comment\">// 3</span>\n    <span class=\"token keyword\">val</span> colorTransitionFraction <span class=\"token operator\">=</span> scrollBehavior<span class=\"token operator\">?</span><span class=\"token punctuation\">.</span>state<span class=\"token operator\">?</span><span class=\"token punctuation\">.</span>overlappedFraction <span class=\"token operator\">?:</span> <span class=\"token number\">0f</span>\n    <span class=\"token keyword\">val</span> fraction <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>colorTransitionFraction <span class=\"token operator\">></span> <span class=\"token number\">0.01f</span><span class=\"token punctuation\">)</span> <span class=\"token number\">1f</span> <span class=\"token keyword\">else</span> <span class=\"token number\">0f</span>\n    <span class=\"token keyword\">val</span> appBarContainerColor <span class=\"token keyword\">by</span> <span class=\"token function\">animateColorAsState</span><span class=\"token punctuation\">(</span>\n        targetValue <span class=\"token operator\">=</span> <span class=\"token function\">lerp</span><span class=\"token punctuation\">(</span>\n            colors<span class=\"token punctuation\">.</span>containerColor<span class=\"token punctuation\">,</span>\n            colors<span class=\"token punctuation\">.</span>scrolledContainerColor<span class=\"token punctuation\">,</span>\n            FastOutLinearInEasing<span class=\"token punctuation\">.</span><span class=\"token function\">transform</span><span class=\"token punctuation\">(</span>fraction<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        animationSpec <span class=\"token operator\">=</span> <span class=\"token function\">spring</span><span class=\"token punctuation\">(</span>stiffness <span class=\"token operator\">=</span> Spring<span class=\"token punctuation\">.</span>StiffnessMediumLow<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        label <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"TopBarSurfaceContainerColorAnimation\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">)</span>\n    <span class=\"token function\">Surface</span><span class=\"token punctuation\">(</span>\n        modifier <span class=\"token operator\">=</span> modifier<span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxWidth</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        color <span class=\"token operator\">=</span> appBarContainerColor<span class=\"token punctuation\">,</span>\n        content <span class=\"token operator\">=</span> content<span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><ol><li>The same <code>TopAppBarColors</code> we used in the <code>ProjectsTopAppBar</code> above should be applied to this surface.</li><li>The same <code>TopAppBarScrollBehavior</code> we pass into the <code>TopAppBar</code> should be provided to the surface.</li><li>We can animate the container colour based on the scroll behaviour using the same approach as <code>TopAppBar</code> uses internally.</li></ol><p>We can now wrap our search bar in the new <code>TopAppBarSurface</code>, passing in the same scroll behaviour.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">topBar <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">Column</span><span class=\"token punctuation\">(</span>verticalArrangement <span class=\"token operator\">=</span> Arrangement<span class=\"token punctuation\">.</span><span class=\"token function\">spacedBy</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token operator\">-</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">ProjectsTopAppBar</span><span class=\"token punctuation\">(</span>\n            onBackClick <span class=\"token operator\">=</span> onBackClick<span class=\"token punctuation\">,</span>\n            scrollBehavior <span class=\"token operator\">=</span> scrollBehavior<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n        <span class=\"token function\">TopAppBarSurface</span><span class=\"token punctuation\">(</span>scrollBehavior <span class=\"token operator\">=</span> scrollBehavior<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">EmbeddedSearchBar</span><span class=\"token punctuation\">(</span>\n                onQueryChange <span class=\"token operator\">=</span> onQueryChange<span class=\"token punctuation\">,</span>\n                isSearchActive <span class=\"token operator\">=</span> isSearchActive<span class=\"token punctuation\">,</span>\n                onActiveChanged <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> isSearchActive <span class=\"token operator\">=</span> it <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>It seems to render with a tiny <code>1dp</code> gap between the two bars, so <code>spacedBy((-1).dp)</code> is included for vertical arrangement. If anyone can work out the cause of the 1dp gap please <a href=\"https://x.com/lordcodes\">reach out</a>.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/d_W4hk63eV-814.webp 814w\"><img src=\"https://www.lordcodes.com/img/d_W4hk63eV-814.jpeg\" alt=\"SearchBar below the TopAppBar\" title=\"SearchBar below the TopAppBar\" class=\"article-img-medium\" width=\"814\" height=\"438\"></picture></p><h2 id=\"active-search-view-styling\" tabindex=\"-1\">Active search view styling</h2><p>When the <code>SearchBar</code> becomes active it expands to form a search view. We need to hide the <code>TopAppBar</code> whilst search is active and also alter its appearance. We will make a few changes to the call to <code>SearchBar(...)</code>.</p><ol><li>When search is active we need to remove the padding we applied earlier.</li><li>We can also animate the content size change to give a clean transition.</li></ol><pre class=\"language-kotlin\"><code class=\"language-kotlin\">modifier <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    modifier\n        <span class=\"token punctuation\">.</span><span class=\"token function\">animateContentSize</span><span class=\"token punctuation\">(</span><span class=\"token function\">spring</span><span class=\"token punctuation\">(</span>stiffness <span class=\"token operator\">=</span> Spring<span class=\"token punctuation\">.</span>StiffnessHigh<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    modifier\n        <span class=\"token punctuation\">.</span><span class=\"token function\">padding</span><span class=\"token punctuation\">(</span>start <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> top <span class=\"token operator\">=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> bottom <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxWidth</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">animateContentSize</span><span class=\"token punctuation\">(</span><span class=\"token function\">spring</span><span class=\"token punctuation\">(</span>stiffness <span class=\"token operator\">=</span> Spring<span class=\"token punctuation\">.</span>StiffnessHigh<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>When active, we can replace the leading search icon with a back button to dismiss the search view.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">leadingIcon <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">IconButton</span><span class=\"token punctuation\">(</span>\n            onClick <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">activeChanged</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>AutoMirrored<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>ArrowBack<span class=\"token punctuation\">,</span>\n                contentDescription <span class=\"token operator\">=</span> <span class=\"token function\">stringResource</span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>string<span class=\"token punctuation\">.</span>navigation_action_back_cd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n                tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>primary<span class=\"token punctuation\">,</span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n            imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>Search<span class=\"token punctuation\">,</span>\n            contentDescription <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n            tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>onSurfaceVariant<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>After a query has been entered into the search view, we can show a clear button.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">trailingIcon <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive <span class=\"token operator\">&amp;&amp;</span> searchQuery<span class=\"token punctuation\">.</span><span class=\"token function\">isNotEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">IconButton</span><span class=\"token punctuation\">(</span>\n            onClick <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n                searchQuery <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span>\n                <span class=\"token function\">onQueryChange</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>Close<span class=\"token punctuation\">,</span>\n                contentDescription <span class=\"token operator\">=</span> <span class=\"token function\">stringResource</span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>string<span class=\"token punctuation\">.</span>search_text_field_clear<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n                tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>primary<span class=\"token punctuation\">,</span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">null</span>\n<span class=\"token punctuation\">}</span></code></pre><p>We can tweak the background colour of the search view when it's active.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">colors <span class=\"token operator\">=</span> SearchBarDefaults<span class=\"token punctuation\">.</span><span class=\"token function\">colors</span><span class=\"token punctuation\">(</span>\n    containerColor <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>background\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>surfaceContainerLow\n    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span></code></pre><p>As the search view is shown instead of the <code>TopAppBar</code>, we need to apply its window insets.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">windowInsets <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    SearchBarDefaults<span class=\"token punctuation\">.</span>windowInsets\n<span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">WindowInsets</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>This completes our customisation of the active search view.</p><details><summary><p>Show full <code>EmbeddedSearchBar</code> code</p></summary><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Composable</span>\n<span class=\"token annotation builtin\">@OptIn</span><span class=\"token punctuation\">(</span>ExperimentalMaterial3Api<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">fun</span> <span class=\"token function\">EmbeddedSearchBar</span><span class=\"token punctuation\">(</span>\n    onQueryChange<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>String<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">,</span>\n    isSearchActive<span class=\"token operator\">:</span> Boolean<span class=\"token punctuation\">,</span>\n    onActiveChanged<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>Boolean<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">,</span>\n    modifier<span class=\"token operator\">:</span> Modifier <span class=\"token operator\">=</span> Modifier<span class=\"token punctuation\">,</span>\n    onSearch<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span>String<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit<span class=\"token punctuation\">)</span><span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> searchQuery <span class=\"token keyword\">by</span> rememberSaveable <span class=\"token punctuation\">{</span> <span class=\"token function\">mutableStateOf</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">val</span> activeChanged<span class=\"token operator\">:</span> <span class=\"token punctuation\">(</span>Boolean<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> active <span class=\"token operator\">-></span>\n        searchQuery <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span>\n        <span class=\"token function\">onQueryChange</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span><span class=\"token punctuation\">)</span>\n        <span class=\"token function\">onActiveChanged</span><span class=\"token punctuation\">(</span>active<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token function\">SearchBar</span><span class=\"token punctuation\">(</span>\n        query <span class=\"token operator\">=</span> searchQuery<span class=\"token punctuation\">,</span>\n        onQueryChange <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> query <span class=\"token operator\">-></span>\n            searchQuery <span class=\"token operator\">=</span> query\n            <span class=\"token function\">onQueryChange</span><span class=\"token punctuation\">(</span>query<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        onSearch <span class=\"token operator\">=</span> onSearch <span class=\"token operator\">?:</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">activeChanged</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        active <span class=\"token operator\">=</span> isSearchActive<span class=\"token punctuation\">,</span>\n        onActiveChange <span class=\"token operator\">=</span> activeChanged<span class=\"token punctuation\">,</span>\n        modifier <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            modifier\n                <span class=\"token punctuation\">.</span><span class=\"token function\">animateContentSize</span><span class=\"token punctuation\">(</span><span class=\"token function\">spring</span><span class=\"token punctuation\">(</span>stiffness <span class=\"token operator\">=</span> Spring<span class=\"token punctuation\">.</span>StiffnessHigh<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            modifier\n                <span class=\"token punctuation\">.</span><span class=\"token function\">padding</span><span class=\"token punctuation\">(</span>start <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> top <span class=\"token operator\">=</span> <span class=\"token number\">2</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> end <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span> bottom <span class=\"token operator\">=</span> <span class=\"token number\">12</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">fillMaxWidth</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">.</span><span class=\"token function\">animateContentSize</span><span class=\"token punctuation\">(</span><span class=\"token function\">spring</span><span class=\"token punctuation\">(</span>stiffness <span class=\"token operator\">=</span> Spring<span class=\"token punctuation\">.</span>StiffnessHigh<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        placeholder <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">Text</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Search\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        leadingIcon <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">IconButton</span><span class=\"token punctuation\">(</span>\n                    onClick <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">activeChanged</span><span class=\"token punctuation\">(</span><span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n                <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                    <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                        imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>AutoMirrored<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>ArrowBack<span class=\"token punctuation\">,</span>\n                        contentDescription <span class=\"token operator\">=</span> <span class=\"token function\">stringResource</span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>string<span class=\"token punctuation\">.</span>navigation_action_back_cd<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n                        tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>primary<span class=\"token punctuation\">,</span>\n                    <span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">}</span>\n            <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                    imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>Search<span class=\"token punctuation\">,</span>\n                    contentDescription <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n                    tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>onSurfaceVariant<span class=\"token punctuation\">,</span>\n                <span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        trailingIcon <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive <span class=\"token operator\">&amp;&amp;</span> searchQuery<span class=\"token punctuation\">.</span><span class=\"token function\">isNotEmpty</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token punctuation\">{</span>\n                <span class=\"token function\">IconButton</span><span class=\"token punctuation\">(</span>\n                    onClick <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n                        searchQuery <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span>\n                        <span class=\"token function\">onQueryChange</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span><span class=\"token punctuation\">)</span>\n                    <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n                <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                    <span class=\"token function\">Icon</span><span class=\"token punctuation\">(</span>\n                        imageVector <span class=\"token operator\">=</span> Icons<span class=\"token punctuation\">.</span>Rounded<span class=\"token punctuation\">.</span>Close<span class=\"token punctuation\">,</span>\n                        contentDescription <span class=\"token operator\">=</span> <span class=\"token function\">stringResource</span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>string<span class=\"token punctuation\">.</span>search_text_field_clear<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n                        tint <span class=\"token operator\">=</span> MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>primary<span class=\"token punctuation\">,</span>\n                    <span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">}</span>\n            <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">null</span>\n        <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        colors <span class=\"token operator\">=</span> SearchBarDefaults<span class=\"token punctuation\">.</span><span class=\"token function\">colors</span><span class=\"token punctuation\">(</span>\n            containerColor <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n                MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>background\n            <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n                MaterialTheme<span class=\"token punctuation\">.</span>colorScheme<span class=\"token punctuation\">.</span>surfaceContainerLow\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        tonalElevation <span class=\"token operator\">=</span> <span class=\"token number\">0</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">,</span>\n        windowInsets <span class=\"token operator\">=</span> <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>isSearchActive<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            SearchBarDefaults<span class=\"token punctuation\">.</span>windowInsets\n        <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token function\">WindowInsets</span><span class=\"token punctuation\">(</span><span class=\"token number\">0</span><span class=\"token punctuation\">.</span>dp<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token comment\">// Search suggestions or results</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></details><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/vkFWHiyf2w-646.webp 646w\"><img src=\"https://www.lordcodes.com/img/vkFWHiyf2w-646.jpeg\" alt=\"Active search view\" title=\"Active search view\" class=\"article-img-medium\" width=\"646\" height=\"390\"></picture></p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>We have built a <code>SearchBar</code> that appears embedded within a <code>TopAppBar</code> that expands into a full-screen search view when focused. The <code>SearchBar</code> is a very customisible component and Jetpack Compose makes it easy to achieve the design we want. This search bar component can now be used throughout our apps to add search to any screen we want.</p>",
			"date_published": "2024-01-29T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/swift-tools-enforced-versions/",
			"url": "https://www.lordcodes.com/articles/swift-tools-enforced-versions/",
			"title": "Installing and running Swift tools with enforced versions",
			"content_html": "<p>Working on Swift projects often involves using tools to help with tasks such as linting using <a href=\"https://github.com/realm/SwiftLint\">SwiftLint</a> or generating code using <a href=\"https://github.com/krzysztofzablocki/Sourcery\">Sourcery</a>. When running tools we want to ensure all developers of the project are using the same version and that a specific version can be chosen to ensure compatibility. For most Swift tools there is the choice of many different installation methods, each with its own benefits and drawbacks, so for many people it might not be obvious what the best option is.</p><p>Before we look at the installation methods, let's consider what we would like to be able to do:</p><ul><li>Enforce versions between team members</li><li>Use a specific version for each project</li><li>Use the same version locally and on CI</li><li>Install tools quickly</li></ul><h2 id=\"installation-options\" tabindex=\"-1\">Installation options</h2><h3 id=\"homebrew\" tabindex=\"-1\">Homebrew</h3><p>Homebrew is a popular package manager for Mac and is useful for installing tools and apps, even allowing use of a <code>Brewfile</code>. Unfortunately, unless a particular version is provided as a formula we cannot install a specific version, instead we would need to require team members to update to the latest version. On top of this some tools may not be published to Homebrew and releases can take longer to arrive.</p><h3 id=\"swift-package-manager-plugins\" tabindex=\"-1\">Swift Package Manager Plugins</h3><p>SPM has support for command and build-time plugins, linking to specific versions. Unfortunately, adding them to Xcode projects only allows running command plugins via the UI, so we would need an SPM package with a <code>Package.swift</code> to run them from the command-line. Depending on the tool we are running we may need to build our own plugin.</p><h3 id=\"cocoapods\" tabindex=\"-1\">Cocoapods</h3><p>Many tools offer installation via <a href=\"https://cocoapods.org\">Cocoapods</a> and running them from the <code>Pods</code> directory. Although we can pin to a specific version, not all tools will be available via Cocoapods. The main issue is that it requires the project to already be using Cocoapods or to add Cocoapods to it, which is Ruby-based.</p><h3 id=\"mint\" tabindex=\"-1\">Mint</h3><p>Swift tools can be built and installed using <a href=\"https://github.com/yonaskolb/mint\">Mint</a>, where we can enforce versions using a <code>Mintfile</code>. We will of course need another method for installing Mint at the right version itself. Many people use Mint happily, however it can be very slow building tools from sources when the version changes, particular on CI where we will need caching to avoid this happening for every build.</p><h3 id=\"binary-or-cloning\" tabindex=\"-1\">Binary or cloning</h3><p>Instead of using a package manager, we could download the tool as a binary from the GitHub release or clone the repository and build it for ourselves. It will be difficult to ensure developers keep tools up-to-date and so the approach will likely involve maintaining some scripts.</p><h2 id=\"an-alternative-approach\" tabindex=\"-1\">An alternative approach</h2><p>For many teams one of these installation methods may be the right approach, however they do come with some potential drawbacks:</p><ul><li>It may not be easy to use or error-prone</li><li>Specifying and enforcing the version may not be possible</li><li>Installation may involve building the tool from sources with its dependencies</li><li>One of the tools may not support a particular installation method</li><li>Our project may not be using Cocoapods or SPM</li></ul><p>For a while I have been successfully using binaries wrapped with scripts to manage download, installation and execution. For developers it is much quicker than any method that builds from sources, it ensures consistent versions and it isn't dependent on use of any external package managers.</p><h3 id=\"the-scripts\" tabindex=\"-1\">The scripts</h3><p>First, we need to create a folder in the project to store the tools and then a script for the tool in question, such as <code>swiftlint.sh</code>. We start the script by specifying the version at the top where it is easy to update.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token assign-left variable\">VERSION</span><span class=\"token operator\">=</span><span class=\"token string\">\"0.54.0\"</span></code></pre><p>We need to calculate the installation directory based on the script location. Make sure to add <code>BuildTools/Tools</code> to the <code>gitignore</code> to avoid binaries or sources being added to source control.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token assign-left variable\">BASEDIR</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">dirname</span> <span class=\"token string\">\"<span class=\"token variable\">$0</span>\"</span><span class=\"token variable\">)</span></span>\n<span class=\"token assign-left variable\">INSTALL_DIR</span><span class=\"token operator\">=</span><span class=\"token string\">\"<span class=\"token variable\">${BASEDIR}</span>/Tools/SwiftLint\"</span>\n<span class=\"token assign-left variable\">EXECUTABLE</span><span class=\"token operator\">=</span><span class=\"token string\">\"<span class=\"token variable\">${INSTALL_DIR}</span>/swiftlint\"</span></code></pre><p>SwiftLint is provided as a binary on the GitHub release so we can download the version we need.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token assign-left variable\">DOWNLOAD_URL</span><span class=\"token operator\">=</span><span class=\"token string\">\"https://github.com/realm/SwiftLint/releases/download\"</span>\n<span class=\"token assign-left variable\">DOWNLOAD_URL</span><span class=\"token operator\">+=</span><span class=\"token string\">\"/<span class=\"token variable\">$VERSION</span>/portable_swiftlint.zip\"</span></code></pre><p>We can now write our install function which will download and unzip the binary, before marking it as safe to execute on Mac.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token keyword\">function</span> <span class=\"token function-name function\">install_tool</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">mkdir</span> <span class=\"token parameter variable\">-p</span> <span class=\"token variable\">$INSTALL_DIR</span>\n    <span class=\"token function\">curl</span> <span class=\"token parameter variable\">-LO</span> <span class=\"token variable\">$DOWNLOAD_URL</span> --output-dir <span class=\"token variable\">$BASEDIR</span>\n    <span class=\"token function\">unzip</span> <span class=\"token variable\">$BASEDIR</span>/portable_swiftlint.zip <span class=\"token parameter variable\">-d</span> <span class=\"token variable\">$INSTALL_DIR</span>\n    <span class=\"token function\">rm</span> <span class=\"token parameter variable\">-rf</span> <span class=\"token variable\">$BASEDIR</span>/portable_swiftlint.zip\n    xattr <span class=\"token parameter variable\">-dr</span> com.apple.quarantine <span class=\"token variable\">$EXECUTABLE</span>\n<span class=\"token punctuation\">}</span></code></pre><p>If the executable is not already installed, we use our function to install it.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">[</span> <span class=\"token operator\">!</span> <span class=\"token parameter variable\">-f</span> <span class=\"token variable\">$EXECUTABLE</span> <span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"<span class=\"token variable\">$EXECUTABLE</span> not found, installing…\"</span>\n    <span class=\"token function\">rm</span> <span class=\"token parameter variable\">-rf</span> <span class=\"token variable\">$INSTALL_DIR</span>\n    install_tool\n<span class=\"token keyword\">fi</span></code></pre><p>If the executable is already installed, we check if it is the right version and re-install it if not.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token assign-left variable\">INSTALLED_VERSION</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span>./$EXECUTABLE <span class=\"token parameter variable\">--version</span><span class=\"token variable\">)</span></span>\n<span class=\"token keyword\">if</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">[</span> <span class=\"token variable\">$VERSION</span> <span class=\"token operator\">!=</span> <span class=\"token variable\">$INSTALLED_VERSION</span> <span class=\"token punctuation\">]</span><span class=\"token punctuation\">]</span>\n<span class=\"token keyword\">then</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"Version out-of-date, re-installing…\"</span>\n    <span class=\"token function\">rm</span> <span class=\"token parameter variable\">-rf</span> <span class=\"token variable\">$INSTALL_DIR</span>\n    install_tool\n<span class=\"token keyword\">fi</span></code></pre><p>Finally, we run the executable, passing any arguments to it.</p><pre class=\"language-shell\"><code class=\"language-shell\">./<span class=\"token variable\">$EXECUTABLE</span> <span class=\"token variable\">${@<span class=\"token operator\">:</span>1}</span></code></pre><p>An installable version of the full script is available <a href=\"https://github.com/lordcodes/swiftlint-cli\">on GitHub</a>.</p><h3 id=\"supported-tools\" tabindex=\"-1\">Supported tools</h3><p>Whenever a binary can be linked to for a particular version by URL, such as GitHub releases, it will be compatible with this approach. If no binary is available the script could be adapted to obtain it via cloning and building from the Git tag as a backup.</p><p>I have been using this approach to run:</p><ul><li>SwiftLint, <a href=\"https://github.com/lordcodes/swiftlint-cli\">installable version on GitHub</a>.</li><li>SwiftFormat, <a href=\"https://github.com/lordcodes/swiftformat-cli\">installable version on GitHub</a></li><li>Sourcery</li></ul><p>The installable versions also include details of using them witin Fastlane, which is great for projects that are using Fastlane for automation.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Using scripts to install and run our tools combines the best of the options, whils keeping performance high:</p><ul><li>Easy to use</li><li>Enforces versions of our tools across the team</li><li>Independent versions for different projects</li><li>Quicker than approaches that checkout and build from source</li><li>Supports local and CI</li></ul><p>It would be unfair if we didn't also consider the drawbacks, in that we have to maintain a script for each tool and the approach only works best when there is a binary available for download.</p><p>Hopefully eventually SPM command plugins will be executable from the command-line for Xcode projects in a performant way. This would make that the preferred approach due to being built-in and not involving maintaining custom scripts to run.</p>",
			"date_published": "2023-12-21T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/authorization-for-okhttp-retrofit/",
			"url": "https://www.lordcodes.com/articles/authorization-for-okhttp-retrofit/",
			"title": "Authorization and retrying of web requests for OkHttp and Retrofit",
			"content_html": "<p>Are you trying to set up authorization for your OkHttp or Retrofit web requests but aren't sure of the best way to do it? Have you explored <code>Interceptor</code> and <code>Authenticator</code> but aren't sure which to use or how best to use them? We will explore these concepts within OkHttp, how to sign web requests and also how to retry them if they fail due to a failed authorization attempt.</p><p>When setting up networking in our apps, authorization is almost always required, as not many remote APIs are completely un-authenticated. OAuth is a common system to use, relying on access tokens to protect our endpoints and refresh tokens to obtain new access tokens once they have expired. The idea is that the access token is added as an Authorization HTTP header on requests to let the API know we have access to a particular resource.</p><p>OkHttp provides <code>Interceptors</code> which can alter web requests before they are sent out and <code>Authenticators</code> that allow us to re-sign and retry requests that have failed due to authorization. It is very common, particularly on Android, to use Retrofit for networking, which uses OkHttp internally and so the same techniques apply to Retrofit as well.</p><p>Let's have a look at how we set this up and how it all works!</p><h2 id=\"signing-requests\" tabindex=\"-1\">Signing requests</h2><p>We will start by setting up our <code>AuthorizationInterceptor</code> that adds the <code>Authorization</code> header to all web requests that are sent off to our remote API.</p><p>Our access tokens are provided by <code>AuthorizationRepository</code>, which either provides a stored access token or obtains a new one if the stored one has already expired. How this process works depends on the authorization each particular API uses, the important part here is that <code>AuthorizationInterceptor</code> has a function it can call to get an access token to sign the web request with.</p><p>Our <code>Interceptor</code> implementation needs to provide an <code>intercept</code> function that can extract the current <code>Request</code>, transform it and then pass this new request back into the chain. The transformation we need to apply involves adding an Authorization header that signs the request with our access token. It is worth noting that the exact format of the header may change depending on what type of tokens each API uses, in our example Bearer tokens are used which are pretty common.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> <span class=\"token function\">AuthorizationInterceptor</span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> authorizationRepository<span class=\"token operator\">:</span> AuthorizationRepository\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> Interceptor <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">intercept</span><span class=\"token punctuation\">(</span>chain<span class=\"token operator\">:</span> Interceptor<span class=\"token punctuation\">.</span>Chain<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Response <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> newRequest <span class=\"token operator\">=</span> chain<span class=\"token punctuation\">.</span><span class=\"token function\">request</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">signedRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> chain<span class=\"token punctuation\">.</span><span class=\"token function\">proceed</span><span class=\"token punctuation\">(</span>newRequest<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> Request<span class=\"token punctuation\">.</span><span class=\"token function\">signedRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Request <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> accessToken <span class=\"token operator\">=</span> authorizationRepository<span class=\"token punctuation\">.</span><span class=\"token function\">fetchFreshAccessToken</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token function\">newBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">header</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Authorization\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Bearer </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">accessToken<span class=\"token punctuation\">.</span>rawToken</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Registering our interceptor just involves adding it to the builder we are using to create our <code>OkHttpClient</code> for either use directly or with Retrofit.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">okHttpClient</span><span class=\"token punctuation\">(</span>authorizationInterceptor<span class=\"token operator\">:</span> AuthorizationInterceptor<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span>\n    OkHttpClient<span class=\"token punctuation\">.</span><span class=\"token function\">Builder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">addInterceptor</span><span class=\"token punctuation\">(</span>authorizationInterceptor<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>All outgoing web requests will now be signed with our access token.</p><h2 id=\"retrying-failed-requests\" tabindex=\"-1\">Retrying failed requests</h2><p>It is possible that our requests may fail with <code>401 Unauthorized</code> due to an issue with the access token we provided. This will usually be due to the access token having expired or being revoked on the server-side. To handle this situation we can build an OkHttp <code>Authenticator</code>, that allows us to catch this case, add a new token and then retry the request.</p><p>We will start by extracting an extension function to set the Authorization header on a request.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> Request<span class=\"token punctuation\">.</span><span class=\"token function\">signWithToken</span><span class=\"token punctuation\">(</span>accessToken<span class=\"token operator\">:</span> AccessToken<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span>\n    <span class=\"token function\">newBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">header</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Authorization\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Bearer </span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">accessToken<span class=\"token punctuation\">.</span>rawToken</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>We will build in a limit on the number of retries to avoid an infinite loop if authorization for a particular endpoint fails entirely. We can determine how many times a request has been retried from the response.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> Response<span class=\"token punctuation\">.</span>retryCount<span class=\"token operator\">:</span> Int\n    <span class=\"token keyword\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">var</span> currentResponse <span class=\"token operator\">=</span> priorResponse\n        <span class=\"token keyword\">var</span> result <span class=\"token operator\">=</span> <span class=\"token number\">0</span>\n        <span class=\"token keyword\">while</span> <span class=\"token punctuation\">(</span>currentResponse <span class=\"token operator\">!=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            result<span class=\"token operator\">++</span>\n            currentResponse <span class=\"token operator\">=</span> currentResponse<span class=\"token punctuation\">.</span>priorResponse\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">return</span> result\n    <span class=\"token punctuation\">}</span></code></pre><p>The implementation of <code>Authenticator</code> receives the response that failed with <code>401 Unauthorized</code> and has to optionally provide a new request to be triggered. If our request has already been retried twice we will simply allow it to fail to avoid an infinite loop. Signing the request is done in the same way as in our <code>AuthorizationInterceptor</code> above.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> <span class=\"token function\">TokenRefreshAuthenticator</span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> authorizationRepository<span class=\"token operator\">:</span> AuthorizationRepository\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> Authenticator <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">authenticate</span><span class=\"token punctuation\">(</span>\n        route<span class=\"token operator\">:</span> Route<span class=\"token operator\">?</span><span class=\"token punctuation\">,</span>\n        response<span class=\"token operator\">:</span> Response\n    <span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Request<span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">{</span>\n        response<span class=\"token punctuation\">.</span>retryCount <span class=\"token operator\">></span> <span class=\"token number\">2</span> <span class=\"token operator\">-></span> <span class=\"token keyword\">null</span>\n        <span class=\"token keyword\">else</span> <span class=\"token operator\">-></span> response<span class=\"token punctuation\">.</span><span class=\"token function\">createSignedRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> Response<span class=\"token punctuation\">.</span><span class=\"token function\">createSignedRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Request<span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> accessToken <span class=\"token operator\">=</span> authenticationRepository<span class=\"token punctuation\">.</span><span class=\"token function\">fetchFreshAccessToken</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        request<span class=\"token punctuation\">.</span><span class=\"token function\">signWithToken</span><span class=\"token punctuation\">(</span>accessToken<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>error<span class=\"token operator\">:</span> Throwable<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        Logger<span class=\"token punctuation\">.</span><span class=\"token function\">error</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">,</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Failed to re-sign request\"</span></span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">null</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Registering our authenticator involves adding it to the builder alongside our interceptor.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">OkHttpClient<span class=\"token punctuation\">.</span><span class=\"token function\">Builder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">addInterceptor</span><span class=\"token punctuation\">(</span>authorizationInterceptor<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">authenticator</span><span class=\"token punctuation\">(</span>tokenRefreshAuthenticator<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">build</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>Web requests that fail with authorization issues will now be re-signed and retried!</p><h2 id=\"refreshing-expired-tokens\" tabindex=\"-1\">Refreshing expired tokens</h2><p>In the above <code>AuthorizationInterceptor</code> and <code>TokenRefreshAuthenticator</code> we obtain an access token using <code>fetchFreshAccessToken</code>. This function has been built to return the stored access token if it hasn't expired yet or to obtain a new one if it has.</p><p>An important note is that the function signatures of both <code>Interceptor</code> and <code>Authenticator</code> require the request to be created or transformed synchronously. The process of refreshing an access token is likely asynchronous due to requiring its own web request to an OAuth API. We therefore need to call this asynchronous token refresh process synchronously, exactly how will depend on how on it is implemented.</p><ul><li>Kotlin Coroutines can use the <a href=\"https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-blocking.html\">runBlocking function</a></li><li>Retrofit Call has a synchronous <a href=\"https://square.github.io/retrofit/2.x/retrofit/retrofit2/Call.html#execute--\">execute function</a></li><li>RxJava Single has a synchronous <a href=\"http://reactivex.io/RxJava/javadoc/io/reactivex/Single.html#blockingGet--\">blockingGet operator</a></li></ul><h2 id=\"multiple-authorization-types\" tabindex=\"-1\">Multiple authorization types</h2><p>In our implementation so far we have assumed that all requests need to be signed in the same way, however, in reality this likely won't be the case. For example, there will likely be requests that need to be performed before a user has signed in such as the account creation request or maybe fetching some form of configuration.</p><p>To incorporate this, we can use the OkHttp Tag API, which can also be used in our Retrofit calls. We will tag our web requests with an <code>AuthType</code> enum that specifies which type of authorization to be used.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">enum</span> <span class=\"token keyword\">class</span> AuthType <span class=\"token punctuation\">{</span>\n    ACCESS_TOKEN<span class=\"token punctuation\">,</span>\n    CLIENT_CREDENTIALS<span class=\"token punctuation\">,</span>\n    NONE<span class=\"token punctuation\">;</span>\n\n    <span class=\"token keyword\">companion</span> <span class=\"token keyword\">object</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">fun</span> <span class=\"token function\">fromRequest</span><span class=\"token punctuation\">(</span>request<span class=\"token operator\">:</span> Request<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> AuthType <span class=\"token operator\">=</span>\n            request<span class=\"token punctuation\">.</span><span class=\"token function\">tag</span><span class=\"token punctuation\">(</span>AuthType<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">.</span>java<span class=\"token punctuation\">)</span> <span class=\"token operator\">?:</span> ACCESS_TOKEN\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>With OkHttp the tag can be specified in the request builder and with Retrofit it can be added using an annotation for a particular call.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">interface</span> CreateAccountRemoteApi <span class=\"token punctuation\">{</span>\n    <span class=\"token annotation builtin\">@POST</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"user/identity\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">suspend</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">createAccount</span><span class=\"token punctuation\">(</span>\n        <span class=\"token annotation builtin\">@Body</span> request<span class=\"token operator\">:</span> CreateAccountRemoteDto<span class=\"token punctuation\">,</span>\n        <span class=\"token annotation builtin\">@Tag</span> authorization<span class=\"token operator\">:</span> AuthType <span class=\"token operator\">=</span> AuthType<span class=\"token punctuation\">.</span>CLIENT_CREDENTIALS\n    <span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> AccountCreatedRemoteDto\n<span class=\"token punctuation\">}</span></code></pre><p>The <code>AuthType</code> can now be extracted and used within our <code>AuthorizationInterceptor</code> and <code>TokenRefreshAuthenticator</code>, to decide how to sign the request.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> <span class=\"token function\">AuthorizationInterceptor</span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> authorizationRepository<span class=\"token operator\">:</span> AuthorizationRepository\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> Interceptor <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">intercept</span><span class=\"token punctuation\">(</span>chain<span class=\"token operator\">:</span> Interceptor<span class=\"token punctuation\">.</span>Chain<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Response <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> newRequest <span class=\"token operator\">=</span> chain<span class=\"token punctuation\">.</span><span class=\"token function\">request</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">signedRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> chain<span class=\"token punctuation\">.</span><span class=\"token function\">proceed</span><span class=\"token punctuation\">(</span>newRequest<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> Request<span class=\"token punctuation\">.</span><span class=\"token function\">signedRequest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">(</span>AuthType<span class=\"token punctuation\">.</span><span class=\"token function\">fromRequest</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        AuthType<span class=\"token punctuation\">.</span>ACCESS_TOKEN <span class=\"token operator\">-></span> <span class=\"token function\">signWithFreshAccessToken</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        AuthType<span class=\"token punctuation\">.</span>CLIENT_CREDENTIALS <span class=\"token operator\">-></span> <span class=\"token function\">signWithClientCredentialsToken</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        AuthType<span class=\"token punctuation\">.</span>NONE <span class=\"token operator\">-></span> <span class=\"token keyword\">this</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Using this approach we can easily control the exact type of authorization each individual endpoint requires, giving us a great level of flexibility.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Adding authorization to web requests for OkHttp and Retrofit can be done without too much complexity, however, without knowing which parts of the API to use it may not be immediately obvious. By using an <code>Interceptor</code> we can avoid requests failing due to being unauthorized and then we can combine this with an <code>Authenticator</code> to also handle the cases where it does unfortunately fail.</p>",
			"date_published": "2020-03-17T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/manage-automation-tasks-using-spm/",
			"url": "https://www.lordcodes.com/articles/manage-automation-tasks-using-spm/",
			"title": "Manage automation tasks using Swift Package Manager",
			"content_html": "<p>Now that we have Swift Package Manager for including framework dependencies, wouldn't it be great if we could use it to install and run our command line tool dependencies as well? What if I told you that this was already possible, allowing you to add tools like <a href=\"https://github.com/realm/SwiftLint\">SwiftLint</a> to your project within <code>Package.swift</code> and run automation tasks easily and with minimal configuration.</p><p>When working on software projects there are usually a set of different scripts for running project automation, or maybe a selection of different command line tools all the developers install on their system. For a Swift project many of these tools are written in Swift, yet we still end up installing them with other package managers such as <a href=\"https://github.com/Homebrew/brew\">Homebrew</a> or <a href=\"https://github.com/yonaskolb/Mint\">Mint</a>. These package managers are fantastic and perfect for installing our tools, however when we already have Swift Package Manager (SPM) it would be great if we could use that directly.</p><p>We will explore setting up all of our command line tool dependencies using Swift Package Manager, discuss how to run them and then move onto how to write automation tasks using a small CLI within our project.</p><h2 id=\"installing-and-running\" tabindex=\"-1\">Installing and running</h2><p>Swift command line tools can be added to our project by simply adding them as a dependency within <code>Package.swift</code>, alongside framework dependencies we may already be using. We will be running the tools directly and so there is no need to add them as dependencies to any of our targets, we just need SPM to download them for us.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">let</span> package <span class=\"token operator\">=</span> <span class=\"token class-name\">Package</span><span class=\"token punctuation\">(</span>\n    name<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Uploader\"</span></span><span class=\"token punctuation\">,</span>\n    products<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">executable</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"uploader-cli\"</span></span><span class=\"token punctuation\">,</span> targets<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"Uploader\"</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    dependencies<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">package</span><span class=\"token punctuation\">(</span>\n            url<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"https://github.com/realm/SwiftLint\"</span></span><span class=\"token punctuation\">,</span>\n            from<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"0.39.1\"</span></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">package</span><span class=\"token punctuation\">(</span>\n            url<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"https://github.com/nicklockwood/SwiftFormat\"</span></span><span class=\"token punctuation\">,</span>\n            from<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"0.44.4\"</span></span>\n        <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">package</span><span class=\"token punctuation\">(</span>\n            url<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"https://github.com/apple/swift-argument-parser\"</span></span><span class=\"token punctuation\">,</span>\n            from<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"0.0.1\"</span></span>\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    targets<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">target</span><span class=\"token punctuation\">(</span>\n            name<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Uploader\"</span></span><span class=\"token punctuation\">,</span>\n            dependencies<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"Uploader\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token string-literal\"><span class=\"token string\">\"ArgumentParser\"</span></span><span class=\"token punctuation\">]</span>\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">)</span></code></pre><p>For our Uploader <code>Package.swift</code> alongside ArgumentParser which we are using as a dependency on our main target, we can include tools: <a href=\"https://github.com/realm/SwiftLint\">SwiftLint</a> and <a href=\"https://github.com/nicklockwood/SwiftFormat\">SwiftFormat</a>. As they are added just like other dependencies, we can specify the version of the command line tool to use, allowing all developers on the project to use the same version. This is especially important for tools that are linting or formatting code, as it means the same rules will be applied for all developers.</p><p>Running our tools is now as simple as using <code>swift run</code>, simple! The same process can be used locally and on CI, which means we get the same versions of the tools in both places!</p><pre><code>swift run swiftlint\nswift run swiftformat .\n</code></pre><h2 id=\"managing-automation-tasks\" tabindex=\"-1\">Managing automation tasks</h2><p>On top of running command line tools as we have done so far, it would be great if we could also run all of our project automation in the same way. We could of course simply use Swift scripts, however, if any of them need dependencies this would need to be managed and having a bunch of different scripts may not be as discoverable as it could be.</p><p>An alternative is that we create a small CLI within <code>Package.swift</code> that provides a set of automation tasks via subcommands that can then be called in a similar way to the lanes in <a href=\"https://github.com/fastlane/fastlane\">Fastlane</a> for those who are familiar with it.</p><p>The first step to creating our CLI is adding a target that will contain the code for our automation tasks.</p><pre class=\"language-swift\"><code class=\"language-swift\">targets<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token operator\">...</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">target</span><span class=\"token punctuation\">(</span>\n        name<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"UploaderTasks\"</span></span><span class=\"token punctuation\">,</span>\n        dependencies<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"ArgumentParser\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token string-literal\"><span class=\"token string\">\"ShellOut\"</span></span><span class=\"token punctuation\">]</span>\n    <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">]</span></code></pre><p>The next step is adding an executable product that uses the new target. Make sure to use a simple name for the executable so that it is easy to run, a personal preference being <code>task</code>. Our automation tasks will now be ran using <code>swift run task TASK_NAME</code>.</p><pre class=\"language-swift\"><code class=\"language-swift\">products<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n    <span class=\"token operator\">...</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">executable</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"task\"</span></span><span class=\"token punctuation\">,</span> targets<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"UploaderTasks\"</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">]</span></code></pre><h2 id=\"the-main-command\" tabindex=\"-1\">The main command</h2><p>Our task executable is developed just like any other CLI, although it will be a simple one containing very little code. We could do it manually within <code>main.swift</code>, however, as we will need to run different tasks as arguments to the main command we will need to be parsing these arguments and making it easy for users to find the tasks they can run. To make this really easy there is the <a href=\"https://github.com/apple/swift-argument-parser\">ArgumentParser</a> framework from Apple.</p><p>Within the <code>main.swift</code> file we create a struct for our main command. This configures the command name, offers text for the help message and provides our tasks as subcommands. We will be providing <code>lint</code>, <code>install</code> and <code>uninstall</code>. To execute our program we call <code>Tasks.main()</code> at the bottom of the <code>main.swift</code>.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">Tasks</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">ParsableCommand</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> configuration <span class=\"token operator\">=</span> <span class=\"token class-name\">CommandConfiguration</span><span class=\"token punctuation\">(</span>\n        commandName<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"tasks\"</span></span><span class=\"token punctuation\">,</span>\n        abstract<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"An automation task runner for Uploader.\"</span></span><span class=\"token punctuation\">,</span>\n        subcommands<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">Linting</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">self</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Install</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">self</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Uninstall</span><span class=\"token punctuation\">.</span><span class=\"token keyword\">self</span><span class=\"token punctuation\">]</span>\n    <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token class-name\">Tasks</span><span class=\"token punctuation\">.</span><span class=\"token function\">main</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>Before creating our first subcommand, we need to make sure it is easy for our subcommands to execute shell commands such as running other CLI tools or scripts. For doing this there is a great framework called <a href=\"https://github.com/JohnSundell/ShellOut\">ShellOut</a>. Rather than calling it directly we can write a small wrapper function that handles errors, streams output as output from our CLI and allows execution to continue after an error.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">func</span> <span class=\"token function-definition function\">runShell</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> command<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> continueOnError<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Bool</span> <span class=\"token operator\">=</span> <span class=\"token boolean\">false</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">do</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">try</span> <span class=\"token function\">shellOut</span><span class=\"token punctuation\">(</span>\n            to<span class=\"token punctuation\">:</span> command<span class=\"token punctuation\">,</span>\n            outputHandle<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>standardOutput<span class=\"token punctuation\">,</span>\n            errorHandle<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>standardError\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">if</span> <span class=\"token operator\">!</span>continueOnError <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">throw</span> <span class=\"token class-name\">ShellError</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">ShellError</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">Error</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">CustomStringConvertible</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> description<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token string-literal\"><span class=\"token string\">\"Failed when running shell command\"</span></span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>If the <code>outputHandle</code> and <code>errorHandle</code> weren't connected to standard output and standard error, we would need to print the output of the <code>shellOut</code> call. By using these handles it will appear in the terminal we are running our task from as it is produced. This means we don't need the output from <code>shellOut</code> or the error it throws as the information has already been shown to the user by the point it is received.</p><h2 id=\"lint\" tabindex=\"-1\">Lint</h2><p>For each task we want to add, we create a subcommand to our main <code>Tasks</code> command. We already registered these above and will now work through creating each of the subcommands, starting with the lint task. We are running <code>SwiftFormat</code> in lint mode and then <code>SwiftLint</code>, allowing execution to continue on error so that we get all of the failures out of both tools.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">Tasks</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">Linting</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">ParsableCommand</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">static</span> <span class=\"token keyword\">var</span> configuration <span class=\"token operator\">=</span> <span class=\"token class-name\">CommandConfiguration</span><span class=\"token punctuation\">(</span>\n            commandName<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"lint\"</span></span><span class=\"token punctuation\">,</span>\n            abstract<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Lint the Uploader codebase, such as static analysis.\"</span></span>\n        <span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">run</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">try</span> <span class=\"token function\">runShell</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"swift run swiftformat . --lint\"</span></span><span class=\"token punctuation\">,</span> continueOnError<span class=\"token punctuation\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">try</span> <span class=\"token function\">runShell</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"swift run swiftlint\"</span></span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>This task is ran using <code>swift run task lint</code>.</p><p>We can create another subcommand to format code using <code>SwiftLint</code> auto-correct and <code>SwiftFormat</code> in its regular mode, feel free to add this to your project in the same way as writing our <code>Linting</code> struct.</p><h2 id=\"install-and-uninstall\" tabindex=\"-1\">Install and uninstall</h2><p>If our Swift project is itself a CLI, our users will need to install and uninstall it, both tasks either being provided by a script or a Makefile. We can offer these tasks via subcommands in our task runner.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">Tasks</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">Install</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">ParsableCommand</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">static</span> <span class=\"token keyword\">var</span> configuration <span class=\"token operator\">=</span> <span class=\"token class-name\">CommandConfiguration</span><span class=\"token punctuation\">(</span>\n            commandName<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"install\"</span></span><span class=\"token punctuation\">,</span>\n            abstract<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Install Uploader for running globally.\"</span></span>\n        <span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">run</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">try</span> <span class=\"token function\">runShell</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"swift build -c release\"</span></span><span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">try</span> <span class=\"token function\">runShell</span><span class=\"token punctuation\">(</span>\n                <span class=\"token string-literal\"><span class=\"token string\">\"install .build/release/uploader-cli /usr/local/bin/uploader\"</span></span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Users can now clone our repository and then run <code>swift run task install</code> to install the application globally on their system. We can also provide an uninstall task, in case they wish to remove our application.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">Tasks</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">Uninstall</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">ParsableCommand</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">static</span> <span class=\"token keyword\">var</span> configuration <span class=\"token operator\">=</span> <span class=\"token class-name\">CommandConfiguration</span><span class=\"token punctuation\">(</span>\n            commandName<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"uninstall\"</span></span><span class=\"token punctuation\">,</span>\n            abstract<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Uninstall Uploader and remove from system.\"</span></span>\n        <span class=\"token punctuation\">)</span>\n\n        <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">run</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">try</span> <span class=\"token function\">runShell</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"rm -f /usr/local/bin/uploader\"</span></span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><h2 id=\"help\" tabindex=\"-1\">Help</h2><p>A really nice feature of ArgumentParser is that it generates a help message from the command structs we have created. This aids discovery of the tasks that can be executed on our project by using <code>swift run task -h</code> or <code>--help</code>.</p><pre class=\"language-terminal\"><code class=\"language-terminal\">OVERVIEW: A task runner for Uploader.\n\nUSAGE: tasks <subcommand>\n\nSUBCOMMANDS:\n  lint        Lint the Uploader codebase, such as static analysis.\n  install     Install Uploader for running globally.\n  uninstall   Uninstall Uploader and remove from system.</subcommand></code></pre><h2 id=\"using-this-on-ci\" tabindex=\"-1\">Using this on CI</h2><p>Now that our command line tools and automation tasks are managed using SPM, using our project on CI services such as <a href=\"https://github.com/features/actions\">GitHub Actions</a> and <a href=\"https://bitrise.io\">Bitrise</a> couldn't be easier. We simply call the same commands we use locally and SPM will handle checking out the correct versions, building and executing our tools.</p><pre class=\"language-terminal\"><code class=\"language-terminal\">swift build\nswift test\nswift run task lint</code></pre><p>Most CI services will also come with built-in support for caching, so we could speed things up by caching the SPM dependencies for future runs.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Swift Package Manager is a really great way to manage our Swift projects and it is nice being able to use the first-party official build tool and dependency manager. Now we can manage all of our automation and project command line tools using SPM as well, bringing all the project configuration together with one tool.</p><p>By building our automation tasks using a CLI within the project, it keeps everything together and easily discoverable. It is also great to be able to build all of this in Swift, meaning the source code and automation is all based on the same language and technologies.</p>",
			"date_published": "2020-03-08T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/the-power-of-lazy-properties-in-kotlin/",
			"url": "https://www.lordcodes.com/articles/the-power-of-lazy-properties-in-kotlin/",
			"title": "The power of lazy properties in Kotlin",
			"content_html": "<p>Do you have properties in your Kotlin types that you want to create later after initialization? You may want to avoid making them nullable, avoid using <code>lateinit</code> or delay an expensive set up process to a later point. In Kotlin this is where <a href=\"https://kotlinlang.org/docs/reference/delegated-properties.html\">delegated properties</a> and <a href=\"https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/lazy.html\">lazy properties</a> in particular can be used, allowing properties to be initialized when they are needed and even keep our main type's initialization simpler and cleaner.</p><p>The idea of making a property <em>lazy</em> is not new to Kotlin and many developers having been doing it in other languages or doing it themselves for ages. There were common approaches to a form of lazy creation in Java, it was hard to live in the Java world without coming across a <code>getInstance()</code> function at some point!</p><p>When it comes to defining lazy properties in Kotlin, they have been brought into being part of the language. There is some new syntax, some different options for initializing them and various situations in which they can be really useful. Let's take a look!</p><h2 id=\"creating-them\" tabindex=\"-1\">Creating them</h2><p>Creating a lazy property in Kotlin is pretty simple, we define it using <code>by lazy</code> and provide a function initializer. At a later point, when the property is first accessed it will be initialized using the function we provided and then on future accesses the cached value will be returned instead. Nifty!</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> bindingController <span class=\"token keyword\">by</span> lazy <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">FilesBindingController</span><span class=\"token punctuation\">(</span>viewModel<span class=\"token operator\">::</span>onFileOpened<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Our <code>bindingController</code> property needs to access the <code>viewModel</code> property in order to be created and so by making it lazy, this can be deferred until it is first used. After <code>bindingController</code> has been initialized, the value will simply be returned every time from then on.</p><h2 id=\"factory-method\" tabindex=\"-1\">Factory method</h2><p>Creating our property may not always be as simple as just calling an initializer and more code may be needed to set it up. In these situations we may wish to move the contents of the lazy function initializer to a factory method on the outer class.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> <span class=\"token function\">TeamRepository</span><span class=\"token punctuation\">(</span>appSchedulers<span class=\"token operator\">:</span> AppSchedulers<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> viewState <span class=\"token keyword\">by</span> <span class=\"token function\">lazy</span><span class=\"token punctuation\">(</span><span class=\"token operator\">::</span>createViewStateLiveData<span class=\"token punctuation\">)</span>\n\n  <span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">createViewStateLiveData</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> LiveData<span class=\"token operator\">&lt;</span>ViewState<span class=\"token operator\">></span> <span class=\"token operator\">=</span>\n      teamRepository<span class=\"token punctuation\">.</span><span class=\"token function\">teamMembersStream</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">.</span><span class=\"token function\">map</span><span class=\"token punctuation\">(</span><span class=\"token operator\">::</span>mapPresentingState<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">.</span><span class=\"token function\">onErrorReturn</span><span class=\"token punctuation\">(</span><span class=\"token operator\">::</span>mapErrorState<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">.</span><span class=\"token function\">startWith</span><span class=\"token punctuation\">(</span>ViewState<span class=\"token punctuation\">.</span>Loading<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">.</span><span class=\"token function\">subscribeOn</span><span class=\"token punctuation\">(</span>appSchedulers<span class=\"token punctuation\">.</span>io<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">.</span><span class=\"token function\">observeOn</span><span class=\"token punctuation\">(</span>appSchedulers<span class=\"token punctuation\">.</span>main<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">.</span><span class=\"token function\">toLiveData</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Moving the initialization code to a factory method can keep the top of our class cleaner and we may find we prefer to keep this set up code out of the way. In some situations we may even be able to use a separate factory object to move the initialization logic to another type or file if we wanted to.</p><h2 id=\"extension\" tabindex=\"-1\">Extension</h2><p>Across our codebase there will be common situations for using lazy properties and so to simplify the call sites we may decide to use an extension function. For example, when using Android <code>ViewModel</code>, each of our Activities will need to retrieve their View Model, which can be done using an extension function on a common base class.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">inline</span> <span class=\"token keyword\">fun</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">reified</span> ViewModelT <span class=\"token operator\">:</span> ViewModel<span class=\"token operator\">></span> ComponentActivity<span class=\"token punctuation\">.</span><span class=\"token function\">bindViewModel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span>\n    <span class=\"token function\">bindViewModel</span><span class=\"token punctuation\">(</span>ViewModelT<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">,</span> viewModelFactoryProvider<span class=\"token punctuation\">)</span>\n\n<span class=\"token annotation builtin\">@PublishedApi</span>\n<span class=\"token keyword\">internal</span> <span class=\"token keyword\">fun</span> <span class=\"token operator\">&lt;</span>ViewModelT <span class=\"token operator\">:</span> ViewModel<span class=\"token operator\">></span> ComponentActivity<span class=\"token punctuation\">.</span><span class=\"token function\">bindViewModel</span><span class=\"token punctuation\">(</span>\n    viewModelType<span class=\"token operator\">:</span> KClass<span class=\"token operator\">&lt;</span>ViewModelT<span class=\"token operator\">></span>\n<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Lazy<span class=\"token operator\">&lt;</span>ViewModelT<span class=\"token operator\">></span> <span class=\"token operator\">=</span> lazy <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">ViewModelProvider</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">get</span><span class=\"token punctuation\">(</span>viewModelType<span class=\"token punctuation\">.</span>java<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Using our new lazy extension function cleans up the initialization call site.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> TeamActivity <span class=\"token operator\">:</span> <span class=\"token function\">FragmentActivity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> viewModel<span class=\"token operator\">:</span> TeamViewModel <span class=\"token keyword\">by</span> <span class=\"token function\">bindViewModel</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>This particular example is now provided by the <a href=\"https://developer.android.com/reference/kotlin/androidx/activity/package-summary#(androidx.activity.ComponentActivity).viewModels(kotlin.Function0)\">AndroidX Activity library</a>.</p><h2 id=\"how-does-it-work%3F\" tabindex=\"-1\">How does it work?</h2><p>Delegated properties work as their name suggests, delegating the property's getter and maybe setter to another type. There are a selection of different delegated property types provided and then on top of this we can write our own. The expression we place after the <code>by</code> keyword is what specifies the delegate that will be used.</p><p>In the case of <code>by lazy</code>, a <code>Lazy</code> delegate type will control access to our property, initializing it on first access and then returning the cached value on subsequent accesses. Users of the property don't need to change how they call it, meaning the read-write behaviour of our property can be changed at the property definition without affecting code that uses it.</p><h2 id=\"multithreading\" tabindex=\"-1\">Multithreading</h2><p>The <code>lazy</code> function has an argument with a default value that controls its synchronization behaviour. If a lazy property is accessed from multiple threads concurrently, synchronization will need to be handled by choosing an appropriate <code>LazyThreadSafetyMode</code>.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> messageId <span class=\"token keyword\">by</span> <span class=\"token function\">lazy</span><span class=\"token punctuation\">(</span>LazyThreadSafetyMode<span class=\"token punctuation\">.</span>NONE<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">createMessageId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span></code></pre><p>The default value <code>SYNCHRONIZED</code> will ensure only a single thread can initialize the property using locks. If we are sure the property will only be accessed by a single thread we can switch to <code>NONE</code> to avoid the overhead of performing the synchronization. There is also the option of using <code>PUBLICATION</code> which allows multiple threads to call the initializer, but only the first returned value being used.</p><p>Most UI code, such as in an <code>Activity</code> or <code>Fragment</code>, will run on the UI thread and so properties that are only used here can use the <code>LazyThreadSafetyMode.NONE</code>. We could even add an extension to avoid specifying this each time.</p><h2 id=\"other-use-cases\" tabindex=\"-1\">Other use cases</h2><p>Lazy is useful wherever we want to delay initialization to a later point, rather than doing it straight away. Without it other options may include a <code>lateinit</code> property which simply &quot;promises&quot; to be initialized before it is used or a nullable property which can have a value or not.</p><p>When we just want to delay initialization, lazy can be a nicer approach to the alternatives. It can be especially helpful for obtaining dependencies whose initialization is out of our control, such as Android View Models from an Activity or Fragment.</p><p>There are times when we need to read a value from somewhere, but don't want it to be retrieved again each time it is needed. An example is reading <code>Bundle</code> extras from an <code>Intent</code>, where using a lazy property would mean on first access the value is read from the <code>Intent</code> and then cached for quicker access in the future.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> OrderDetailActivity <span class=\"token operator\">:</span> <span class=\"token function\">FragmentActivity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">val</span> orderId <span class=\"token keyword\">by</span> lazy <span class=\"token punctuation\">{</span>\n      intent<span class=\"token punctuation\">.</span>getParcelableExtra<span class=\"token operator\">&lt;</span>OrderId<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>EXTRA_ORDER_ID<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Delegated properties and lazy properties in particular are a great feature to have at our disposal. The give us flexibility over how our properties are initialized and accessed. It is really nice to be able to make a property lazy without having to alter how it is used in calling code.</p>",
			"date_published": "2020-03-01T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/uploading-a-file-with-progress-in-kotlin/",
			"url": "https://www.lordcodes.com/articles/uploading-a-file-with-progress-in-kotlin/",
			"title": "Uploading a file with progress in Kotlin",
			"content_html": "<p>Do you want to upload a file using the clean Retrofit syntax, but aren't sure how to receive the result as well as the upload progress? We will be using Retrofit to perform the file upload, building an implementation that is able to receive the completion progress at intervals and then complete with the remote API response.</p><p>Whilst long-running operations are happening, it is nice for the user to see that activity is occurring, such as a progress view being displayed. For the case of a file upload we can show the real progress, which can be represented by the number of bytes transmitted out of the total file size.</p><p>We will use the APIs available to us in <a href=\"https://square.github.io/retrofit/\">Retrofit</a>, <a href=\"https://square.github.io/okhttp/\">OkHttp</a> and <a href=\"https://square.github.io/okio/\">Okio</a> to build a class that can be used whenever we want a request to publish its progress to whoever wishes to observe it!</p><h2 id=\"endpoint\" tabindex=\"-1\">Endpoint</h2><p>We are developing a messaging application that is able to attach a file to a message thread. It is worth noting that we are using Kotlin Coroutines, however, it can be altered to use regular callbacks or a reactive framework such as RxJava.</p><p>Our endpoint is a POST request that contains a multipart body, consisting of the filename, file MIME type, file size and the file itself. We can define it using Retrofit, specifying the required parts.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Multipart</span>\n<span class=\"token annotation builtin\">@POST</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"file\"</span></span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">suspend</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">uploadFile</span><span class=\"token punctuation\">(</span>\n    <span class=\"token annotation builtin\">@Part</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"name\"</span></span><span class=\"token punctuation\">)</span> filename<span class=\"token operator\">:</span> RequestBody<span class=\"token punctuation\">,</span>\n    <span class=\"token annotation builtin\">@Part</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"type\"</span></span><span class=\"token punctuation\">)</span> mimeType<span class=\"token operator\">:</span> RequestBody<span class=\"token punctuation\">,</span>\n    <span class=\"token annotation builtin\">@Part</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"size\"</span></span><span class=\"token punctuation\">)</span> fileSize<span class=\"token operator\">:</span> RequestBody<span class=\"token punctuation\">,</span>\n    <span class=\"token annotation builtin\">@Part</span> filePart<span class=\"token operator\">:</span> MultipartBody<span class=\"token punctuation\">.</span>Part<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> FileUploadedRemoteDto</code></pre><h2 id=\"counting-progress\" tabindex=\"-1\">Counting progress</h2><p>If we just wanted to upload the file without any progress, we would simply convert the file to a request body and send it in the request.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">createUploadRequestBody</span><span class=\"token punctuation\">(</span>file<span class=\"token operator\">:</span> File<span class=\"token punctuation\">,</span> mimeType<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span>\n    file<span class=\"token punctuation\">.</span><span class=\"token function\">asRequestBody</span><span class=\"token punctuation\">(</span>mimeType<span class=\"token punctuation\">.</span><span class=\"token function\">toMediaType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre><p>Monitoring upload progress can be achieved by using our own <code>CountingRequestBody</code> which wraps around the file <code>RequestBody</code> that would have been used before. The data that is transmitted is the same as before, allowing the raw file <code>RequestBody</code> to be delegated to for the content type and content length.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> <span class=\"token function\">CountingRequestBody</span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> requestBody<span class=\"token operator\">:</span> RequestBody<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> onProgressUpdate<span class=\"token operator\">:</span> CountingRequestListener<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">RequestBody</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">contentType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> requestBody<span class=\"token punctuation\">.</span><span class=\"token function\">contentType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token annotation builtin\">@Throws</span><span class=\"token punctuation\">(</span>IOException<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">contentLength</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> requestBody<span class=\"token punctuation\">.</span><span class=\"token function\">contentLength</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token operator\">..</span><span class=\"token punctuation\">.</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Transmitting the request body is performed by writing it to a <code>Sink</code>, we will wrap the default sink with our own one that counts the bytes that are transmitted and reports them back via a progress callback.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">typealias</span> CountingRequestListener <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span>\n    bytesWritten<span class=\"token operator\">:</span> Long<span class=\"token punctuation\">,</span>\n    contentLength<span class=\"token operator\">:</span> Long<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit\n\n<span class=\"token keyword\">class</span> <span class=\"token function\">CountingSink</span><span class=\"token punctuation\">(</span>\n    sink<span class=\"token operator\">:</span> Sink<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> requestBody<span class=\"token operator\">:</span> RequestBody<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> onProgressUpdate<span class=\"token operator\">:</span> CountingRequestListener<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">ForwardingSink</span><span class=\"token punctuation\">(</span>sink<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">var</span> bytesWritten <span class=\"token operator\">=</span> <span class=\"token number\">0L</span>\n\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">write</span><span class=\"token punctuation\">(</span>source<span class=\"token operator\">:</span> Buffer<span class=\"token punctuation\">,</span> byteCount<span class=\"token operator\">:</span> Long<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">write</span><span class=\"token punctuation\">(</span>source<span class=\"token punctuation\">,</span> byteCount<span class=\"token punctuation\">)</span>\n\n        bytesWritten <span class=\"token operator\">+=</span> byteCount\n        <span class=\"token function\">onProgressUpdate</span><span class=\"token punctuation\">(</span>\n            bytesWritten<span class=\"token punctuation\">,</span>\n            requestBody<span class=\"token punctuation\">.</span><span class=\"token function\">contentLength</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Within <code>CountingRequestBody</code> we can wrap the default sink into our new <code>CountingSink</code> and write to a buffered version of that, in order to both transmit the file and observe its progress.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">class</span> <span class=\"token function\">CountingRequestBody</span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> requestBody<span class=\"token operator\">:</span> RequestBody<span class=\"token punctuation\">,</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> onProgressUpdate<span class=\"token operator\">:</span> CountingRequestListener<span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">RequestBody</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">contentType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> requestBody<span class=\"token punctuation\">.</span><span class=\"token function\">contentType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token annotation builtin\">@Throws</span><span class=\"token punctuation\">(</span>IOException<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">contentLength</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> requestBody<span class=\"token punctuation\">.</span><span class=\"token function\">contentLength</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token annotation builtin\">@Throws</span><span class=\"token punctuation\">(</span>IOException<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">writeTo</span><span class=\"token punctuation\">(</span>sink<span class=\"token operator\">:</span> BufferedSink<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> countingSink <span class=\"token operator\">=</span> <span class=\"token function\">CountingSink</span><span class=\"token punctuation\">(</span>sink<span class=\"token punctuation\">,</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span> onProgressUpdate<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">val</span> bufferedSink <span class=\"token operator\">=</span> countingSink<span class=\"token punctuation\">.</span><span class=\"token function\">buffer</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n        requestBody<span class=\"token punctuation\">.</span><span class=\"token function\">writeTo</span><span class=\"token punctuation\">(</span>bufferedSink<span class=\"token punctuation\">)</span>\n\n        bufferedSink<span class=\"token punctuation\">.</span><span class=\"token function\">flush</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><h2 id=\"the-result\" tabindex=\"-1\">The result</h2><p>Whilst observing the upload progress, there will either be progress or a completed response, the perfect candidate for a sealed class. This will allow <code>CountingRequestResult</code> to be the return type and callers can handle both progress updates and the completed result.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">sealed</span> <span class=\"token keyword\">class</span> CountingRequestResult<span class=\"token operator\">&lt;</span>ResultT<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> Progress<span class=\"token operator\">&lt;</span>ResultT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>\n        <span class=\"token keyword\">val</span> progressFraction<span class=\"token operator\">:</span> Double\n    <span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> CountingRequestResult<span class=\"token operator\">&lt;</span>ResultT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> Completed<span class=\"token operator\">&lt;</span>ResultT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>\n        <span class=\"token keyword\">val</span> result<span class=\"token operator\">:</span> ResultT\n    <span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> CountingRequestResult<span class=\"token operator\">&lt;</span>ResultT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><h2 id=\"perform-the-upload\" tabindex=\"-1\">Perform the upload</h2><p>Now that we have a way of uploading a file and receiving the upload progress, we can write our <code>FileUploader</code>. Creating the request body for our upload request involves using a <code>CountingRequestBody</code> that reports progress and completion to a <code>MutableStateFlow</code> (or another reactive type).</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">createUploadRequestBody</span><span class=\"token punctuation\">(</span>\n    file<span class=\"token operator\">:</span> File<span class=\"token punctuation\">,</span>\n    mimeType<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span>\n    progressEmitter<span class=\"token operator\">:</span> MutableStateFlow<span class=\"token operator\">&lt;</span>Double<span class=\"token operator\">></span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> RequestBody <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> fileRequestBody <span class=\"token operator\">=</span> file<span class=\"token punctuation\">.</span><span class=\"token function\">asRequestBody</span><span class=\"token punctuation\">(</span>mimeType<span class=\"token punctuation\">.</span><span class=\"token function\">toMediaType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">CountingRequestBody</span><span class=\"token punctuation\">(</span>fileRequestBody<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> bytesWritten<span class=\"token punctuation\">,</span> contentLength <span class=\"token operator\">-></span>\n        <span class=\"token keyword\">val</span> progress <span class=\"token operator\">=</span> <span class=\"token number\">1.0</span> <span class=\"token operator\">*</span> bytesWritten <span class=\"token operator\">/</span> contentLength\n        progressEmitter<span class=\"token punctuation\">.</span><span class=\"token function\">update</span> <span class=\"token punctuation\">{</span> progress <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The upload request consists of using the Retrofit function we implemented at the beginning, providing the file details and the created request body that will count progress. The Retrofit definition and the format of the request parts will depend on how each particular API is put together. Here we are using a request that contains various plaintext parts for the file details and then one for the file to be uploaded.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">suspend</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">performFileUpload</span><span class=\"token punctuation\">(</span>\n    filename<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span>\n    file<span class=\"token operator\">:</span> File<span class=\"token punctuation\">,</span>\n    mimeType<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span>\n    progressEmitter<span class=\"token operator\">:</span> MutableStateFlow<span class=\"token operator\">&lt;</span>Double<span class=\"token operator\">></span><span class=\"token punctuation\">,</span>\n<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> FileUploadedRemoteDto <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> requestBody <span class=\"token operator\">=</span> <span class=\"token function\">createUploadRequestBody</span><span class=\"token punctuation\">(</span>file<span class=\"token punctuation\">,</span> mimeType<span class=\"token punctuation\">,</span> progressEmitter<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> remoteApi<span class=\"token punctuation\">.</span><span class=\"token function\">uploadFile</span><span class=\"token punctuation\">(</span>\n        filename <span class=\"token operator\">=</span> filename<span class=\"token punctuation\">.</span><span class=\"token function\">toRequestBody</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"text/plain\"</span></span><span class=\"token punctuation\">.</span><span class=\"token function\">toMediaType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        mimeType <span class=\"token operator\">=</span> mimeType<span class=\"token punctuation\">.</span><span class=\"token function\">toRequestBody</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"text/plain\"</span></span><span class=\"token punctuation\">.</span><span class=\"token function\">toMediaType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        fileSize <span class=\"token operator\">=</span> file\n            <span class=\"token punctuation\">.</span><span class=\"token function\">length</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">.</span><span class=\"token function\">toRequestBody</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"text/plain\"</span></span><span class=\"token punctuation\">.</span><span class=\"token function\">toMediaType</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n        filePart <span class=\"token operator\">=</span> MultipartBody<span class=\"token punctuation\">.</span>Part<span class=\"token punctuation\">.</span><span class=\"token function\">createFormData</span><span class=\"token punctuation\">(</span>\n            name <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"files[]\"</span></span><span class=\"token punctuation\">,</span>\n            filename <span class=\"token operator\">=</span> filename<span class=\"token punctuation\">,</span>\n            body <span class=\"token operator\">=</span> requestBody<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Our main upload function can put together all of these parts to create a single result flow. We will be able to collect this to get progress updates as well as the final result.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">uploadFile</span><span class=\"token punctuation\">(</span>\n    filename<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span>\n    file<span class=\"token operator\">:</span> File<span class=\"token punctuation\">,</span>\n    mimeType<span class=\"token operator\">:</span> String\n<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Flow<span class=\"token operator\">&lt;</span>FileUploadRemoteResult<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> progressEmitter <span class=\"token operator\">=</span> <span class=\"token function\">MutableStateFlow</span><span class=\"token punctuation\">(</span><span class=\"token number\">0.0</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">val</span> progressStream <span class=\"token operator\">=</span> progressEmitter\n        <span class=\"token punctuation\">.</span>transformWhile<span class=\"token operator\">&lt;</span>Double<span class=\"token punctuation\">,</span> FileUploadRemoteResult<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span> progress <span class=\"token operator\">-></span>\n            <span class=\"token function\">emit</span><span class=\"token punctuation\">(</span>CountingRequestResult<span class=\"token punctuation\">.</span><span class=\"token function\">Progress</span><span class=\"token punctuation\">(</span>progress<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n            progress <span class=\"token operator\">&lt;</span> <span class=\"token number\">1.0</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">val</span> resultStream <span class=\"token operator\">=</span> flow <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> uploadResult <span class=\"token operator\">=</span> <span class=\"token function\">performFileUpload</span><span class=\"token punctuation\">(</span>\n            filename<span class=\"token punctuation\">,</span>\n            file<span class=\"token punctuation\">,</span>\n            mimeType<span class=\"token punctuation\">,</span>\n            progressEmitter<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n        <span class=\"token function\">emit</span><span class=\"token punctuation\">(</span>CountingRequestResult<span class=\"token punctuation\">.</span><span class=\"token function\">Completed</span><span class=\"token punctuation\">(</span>uploadResult<span class=\"token punctuation\">.</span>result<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">merge</span><span class=\"token punctuation\">(</span>progressStream<span class=\"token punctuation\">,</span> resultStream<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">typealias</span> FileUploadRemoteResult <span class=\"token operator\">=</span> CountingRequestResult<span class=\"token operator\">&lt;</span>FileUploadedRemoteDto<span class=\"token operator\">></span></code></pre><p>We can now upload a file to our API and update a view as the request progresses, which is nice for noticeably long operations like uploading larger files.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">uploader<span class=\"token punctuation\">.</span><span class=\"token function\">uploadFile</span><span class=\"token punctuation\">(</span>request<span class=\"token punctuation\">.</span>filename<span class=\"token punctuation\">,</span> request<span class=\"token punctuation\">.</span>file<span class=\"token punctuation\">,</span> request<span class=\"token punctuation\">.</span>mimeType<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">distinctUntilChanged</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">.</span><span class=\"token function\">collect</span> <span class=\"token punctuation\">{</span> uploadResult <span class=\"token operator\">-></span>\n        <span class=\"token comment\">// Update progress in UI</span>\n        fileUploadingState<span class=\"token punctuation\">.</span><span class=\"token function\">update</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">inProgressState</span><span class=\"token punctuation\">(</span>uploadResult<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span>\n\n        <span class=\"token comment\">// Get uploaded file</span>\n        <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>uploadResult<span class=\"token punctuation\">.</span>status <span class=\"token keyword\">is</span> CountingRequestResult<span class=\"token punctuation\">.</span>Completed<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            uploadedFileState<span class=\"token punctuation\">.</span><span class=\"token function\">update</span> <span class=\"token punctuation\">{</span> uploadResult<span class=\"token punctuation\">.</span>status<span class=\"token punctuation\">.</span>result <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span></code></pre><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Monitoring the progress of a web request may not be immediately obvious when reading through the Retrofit API, however, the powerful APIs of OkHttp and Okio can get the job done nicely. The solution we have developed can be used for any web request, as the counting process can be wrapped around any <code>RequestBody</code> that needs to be sent in a request.</p>",
			"date_published": "2020-02-25T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/simplified-launching-of-android-activities/",
			"url": "https://www.lordcodes.com/articles/simplified-launching-of-android-activities/",
			"title": "Simplified launching of Android Activities",
			"content_html": "<p>Extension functions are really great for making life easier, allowing us to add functionality to types that aren't our own. One area we can use an extension is for launching Android Activities more easily.</p><p>We can build an extension that allows all Activities to be launched via a generic type argument. An optional request code can be passed to the function, which controls whether <code>startActivity</code> or <code>startActivityForResult</code> is used to launch the Activity. By providing an intent builder function, the <code>Intent</code> that is fired can be customised.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">inline</span> <span class=\"token keyword\">fun</span> <span class=\"token operator\">&lt;</span><span class=\"token keyword\">reified</span> ActivityT <span class=\"token operator\">:</span> Activity<span class=\"token operator\">></span> Activity<span class=\"token punctuation\">.</span><span class=\"token function\">startActivity</span><span class=\"token punctuation\">(</span>\n    requestCode<span class=\"token operator\">:</span> Int<span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">,</span>\n    intentBuilder<span class=\"token operator\">:</span> Intent<span class=\"token punctuation\">.</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> Unit <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> intent <span class=\"token operator\">=</span> <span class=\"token function\">Intent</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span> ActivityT<span class=\"token operator\">::</span><span class=\"token keyword\">class</span><span class=\"token punctuation\">.</span>java<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">apply</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">intentBuilder</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span>requestCode <span class=\"token operator\">==</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">startActivity</span><span class=\"token punctuation\">(</span>intent<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">startActivityForResult</span><span class=\"token punctuation\">(</span>intent<span class=\"token punctuation\">,</span> requestCode<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fun</span> <span class=\"token function\">startContactCreation</span><span class=\"token punctuation\">(</span>fromActivity<span class=\"token operator\">:</span> Activity<span class=\"token punctuation\">,</span> requestCode<span class=\"token operator\">:</span> Int<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    fromActivity<span class=\"token punctuation\">.</span>startActivity<span class=\"token operator\">&lt;</span>ConnectionCreationActivity<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>requestCode<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">putExtra</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"source\"</span></span><span class=\"token punctuation\">,</span> ConnectionCreationSource<span class=\"token punctuation\">.</span>CONNECTIONS<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2020-02-25T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/protecting-secrets-in-an-android-project/",
			"url": "https://www.lordcodes.com/articles/protecting-secrets-in-an-android-project/",
			"title": "Protecting secrets in an Android project",
			"content_html": "<p>Would you like to include secrets such as API keys into your Android project, but also want to protect them and keep them safe? We can use features of Gradle, environment variables, obfuscation and encryption, to keep them out of Git and to keep them secure.</p><p>When developing apps we will often need to use secret values that we don't want anyone to get access to, such as tokens, IDs and API keys. There are many reasons they may be needed in our source code and in Gradle scripts, the most common being when we are asked to provide one to authenticate with a third-party API.</p><p>We will examine a selection of techniques that we can apply, providing protection for our secrets and preventing them from sitting in plaintext, in plain sight!</p><h2 id=\"why\" tabindex=\"-1\">Why</h2><p>When following the set up instructions to integrate a new library, we are usually told to put the API key in the <code>AndroidManifest.xml</code>, in the source code or in a Gradle file. These suggestions will result in the secrets being added to source control and to be easily obtainable in plaintext by decompiling our app.</p><p>There are more secure ways of managing our secrets and through these tips we can make them significantly harder to obtain. It is worth remembering that our app is published and installed, meaning people will be able to take it apart and try and find secret values within it. All we can do as developers is to apply an appropriate level of security and do our best to keep these secrets safe. When it comes to API keys and tokens, there are also techniques that can be applied on the backend-side to detect fraudulent use and block access using those credentials.</p><h2 id=\"where-to-store-them\" tabindex=\"-1\">Where to store them</h2><p>Gradle allows values to be passed in via Gradle properties, these can be passed on the command line or stored in a project-level or user-level properties file. A great way to handle our secrets is to use the user-level file on our filesystem, keeping them out of the project and out of source control. If we were to remove the project from our system and then re-clone it the secrets would still be there and we also have the possibility to include the same secrets into multiple projects without requiring extra set up.</p><p>By storing them at a user-level and keeping them out of Git, it means everyone with read-access to the source code doesn't automatically receive the secrets and if our source control system was compromised the attackers wouldn't obtain all of our secrets alongside the source code.</p><p>The file is stored within our user directory:</p><ul><li>On Mac or Linux: <code>/Users/&lt;you&gt;/.gradle/gradle.properties</code></li><li>On Windows: <code>C:\\Users\\&lt;you&gt;\\.gradle\\gradle.properties</code></li></ul><p>We add a property for each secret to the file, keeping in mind it is user-level and so we will want something to signify which app or project the secret corresponds to.</p><pre class=\"language-properties\"><code class=\"language-properties\"><span class=\"token key attr-name\">GameCatalogueApp_UploadKeystore_KeyPassword</span><span class=\"token punctuation\">=</span><span class=\"token value attr-value\">aaaabbbbcccc</span>\n<span class=\"token key attr-name\">GameCatalogueApp_AuthClientSecret</span><span class=\"token punctuation\">=</span><span class=\"token value attr-value\">123456789</span>\n<span class=\"token key attr-name\">GameCatalogueApp_Pusher_APIKey</span><span class=\"token punctuation\">=</span><span class=\"token value attr-value\">ksldjalksdjskald</span></code></pre><h2 id=\"using-values\" tabindex=\"-1\">Using values</h2><p>Accessing the values within our Android project is as simple as reading them as a Gradle property and using them how we wish. If the value is needed within a Gradle script, such as to pass in a keystore password, it can just be read and used as it is. We are using a handy extension to get the property and return an empty string if it isn't present, to avoid the null value. If our secrets are set up correctly, they won't be missing.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">signingConfigs <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"upload\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    storePassword <span class=\"token operator\">=</span> <span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span>\n      <span class=\"token string-literal singleline\"><span class=\"token string\">\"GameCatalogueApp_UploadKeystore_KeyPassword\"</span></span>\n    <span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fun</span> Project<span class=\"token punctuation\">.</span><span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span>name<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> String <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> property <span class=\"token operator\">=</span> <span class=\"token function\">findProperty</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> String<span class=\"token operator\">?</span>\n    <span class=\"token keyword\">return</span> property <span class=\"token operator\">?:</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p>Using the values from our source code requires them to be passed through using either <code>resValue</code> or <code>buildConfigField</code>, depending on whether we want them as an Android resource or as a property on the <code>BuildConfig</code> object. One quirk with <code>buildConfigField</code> is the String containing the property value needs to have quotes within it, in order for <code>BuildConfig</code> to be correctly generated.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">defaultConfig <span class=\"token punctuation\">{</span>\n  <span class=\"token function\">buildConfigField</span><span class=\"token punctuation\">(</span>\n    <span class=\"token string-literal singleline\"><span class=\"token string\">\"String\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token string-literal singleline\"><span class=\"token string\">\"AUTH_CLIENT_SECRET\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">buildConfigProperty</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"GameCatalogueApp_AuthClientSecret\"</span></span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">)</span>\n\n  <span class=\"token function\">resValue</span><span class=\"token punctuation\">(</span>\n    <span class=\"token string-literal singleline\"><span class=\"token string\">\"string\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token string-literal singleline\"><span class=\"token string\">\"pusher_key\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"GameCatalogueApp_Pusher_APIKey\"</span></span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fun</span> Project<span class=\"token punctuation\">.</span><span class=\"token function\">buildConfigProperty</span><span class=\"token punctuation\">(</span>name<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\\\"</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\"><span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span></span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\\\"\"</span></span></code></pre><h2 id=\"what-about-ci\" tabindex=\"-1\">What about CI</h2><p>It would be very common for our project to be built on a continuous integration (CI) system or service, such as Bitrise or Jenkins. If this is the case we will need our secrets to be available on CI and passed through to the build environment. A handy trick here is that we can set the secrets as environment variables that use the same names as the Gradle properties. The functions we use to read their values within Gradle can then check for both a Gradle property or an environment variable and use whichever is found.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> Project<span class=\"token punctuation\">.</span><span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span>name<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> String <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> property <span class=\"token operator\">=</span> <span class=\"token function\">findProperty</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> String<span class=\"token operator\">?</span>\n    <span class=\"token keyword\">return</span> property <span class=\"token operator\">?:</span> <span class=\"token function\">environmentVariable</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fun</span> <span class=\"token function\">environmentVariable</span><span class=\"token punctuation\">(</span>name<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> System<span class=\"token punctuation\">.</span><span class=\"token function\">getenv</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span> <span class=\"token operator\">?:</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span></code></pre><p>Of course, this means environment variables can also be used locally if we would prefer, however, using Gradle properties is a very simple process.</p><h2 id=\"encrypt-them\" tabindex=\"-1\">Encrypt them</h2><p>Even though our secrets are now usable and kept separate to the source code, it would still be fairly simple to decompile the app and extract our secrets in plain text. We can take our solution further by encrypting the values before they are stored and then decrypting them at runtime.</p><p>There are various options for encryption, including built-in options or third-party libraries. One possibility is <a href=\"https://github.com/cossacklabs/themis\">Themis</a>, which is easy to use and provides strong cryptographic techniques, along with a unified API between Android and iOS. Unless there is a skilled cryptographer working on the project, it may be a good idea to use a higher-level encryption API to avoid mistakes being made which weaken applied security measures.</p><p>In order to encrypt our data we will need an encryption key.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">GameCatalogueApp_EncryptionKey<span class=\"token operator\">=</span>super_secret_key\n\n<span class=\"token function\">buildConfigField</span><span class=\"token punctuation\">(</span>\n  <span class=\"token string-literal singleline\"><span class=\"token string\">\"String\"</span></span><span class=\"token punctuation\">,</span>\n  <span class=\"token string-literal singleline\"><span class=\"token string\">\"ENCRYPTION_KEY\"</span></span><span class=\"token punctuation\">,</span>\n  <span class=\"token function\">buildConfigProperty</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"GameCatalogueApp_EncryptionKey\"</span></span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span></code></pre><p>We can provide some obfuscation and protection to our key by applying runtime transformations to it, resulting in the &quot;real&quot; key we will actually use. By doing this an attacker would need to decompile the source code and work out from the obfuscated code which operations were applied to the key.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">generateKey</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> ByteArray <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">val</span> rawKey <span class=\"token operator\">=</span> <span class=\"token function\">buildString</span><span class=\"token punctuation\">(</span><span class=\"token number\">5</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token function\">byteArrayOf</span><span class=\"token punctuation\">(</span><span class=\"token number\">0x12</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0x27</span><span class=\"token punctuation\">,</span> <span class=\"token number\">0x42</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">base64EncodedString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token number\">500</span> <span class=\"token operator\">+</span> <span class=\"token number\">6</span> <span class=\"token operator\">/</span> <span class=\"token number\">7</span> <span class=\"token operator\">*</span> <span class=\"token number\">89</span><span class=\"token punctuation\">)</span>\n      <span class=\"token function\">append</span><span class=\"token punctuation\">(</span>BuildConfig<span class=\"token punctuation\">.</span>ENCRYPTION_KEY<span class=\"token punctuation\">)</span>\n      <span class=\"token function\">append</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"pghy^%£aft\"</span></span><span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">return</span> rawKey<span class=\"token punctuation\">.</span><span class=\"token function\">toByteArray</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">fun</span> ByteArray<span class=\"token punctuation\">.</span><span class=\"token function\">base64EncodedString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> Base64<span class=\"token punctuation\">.</span><span class=\"token function\">encodeToString</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span> Base64<span class=\"token punctuation\">.</span>NO_WRAP<span class=\"token punctuation\">)</span></code></pre><p>Here we have only applied some fairly simple operations onto the key to demonstrate the idea, the concept could be taken much further and make the key harder to crack.</p><p>Now that we have our encryption key ready to go, we can use a Themis <code>SecureCell</code> to turn our raw String data into an encrypted byte string.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">encrypt</span><span class=\"token punctuation\">(</span>message<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> ByteArray <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> encryptionKey <span class=\"token operator\">=</span> <span class=\"token function\">generateKey</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">val</span> cell <span class=\"token operator\">=</span> <span class=\"token function\">SecureCell</span><span class=\"token punctuation\">(</span>encryptionKey<span class=\"token punctuation\">,</span> SecureCell<span class=\"token punctuation\">.</span>MODE_SEAL<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">val</span> protectedData <span class=\"token operator\">=</span> cell<span class=\"token punctuation\">.</span><span class=\"token function\">protect</span><span class=\"token punctuation\">(</span>\n        encryptionContext<span class=\"token punctuation\">,</span> message<span class=\"token punctuation\">.</span><span class=\"token function\">toByteArray</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> protectedData<span class=\"token punctuation\">.</span>protectedData\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> encryptionContext<span class=\"token operator\">:</span> ByteArray<span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">null</span></code></pre><p>To store our encrypted secret we can encode the produced <code>ByteArray</code> into a base 64 encoded string. The same key generation code could be added to a script or we could just run the app, encrypt the secret and print out the value for us to copy.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">val</span> encypted <span class=\"token operator\">=</span> <span class=\"token function\">EncryptionEngine</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">encrypt</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"raw_secret_value\"</span></span><span class=\"token punctuation\">)</span>\nLog<span class=\"token punctuation\">.</span><span class=\"token function\">d</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"ENCRYPTED\"</span></span><span class=\"token punctuation\">,</span> encypted<span class=\"token punctuation\">.</span><span class=\"token function\">base64EncodedString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre><p>The Gradle properties or our CI environment variables can now be replaced with encrypted versions.</p><h2 id=\"decrypt-them\" tabindex=\"-1\">Decrypt them</h2><p>At runtime we will first need to convert the base 64 encoded version into an encrypted <code>ByteArray</code>.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">val</span> encryptedDaya <span class=\"token operator\">=</span> Base64<span class=\"token punctuation\">.</span><span class=\"token function\">decode</span><span class=\"token punctuation\">(</span>secretAsBase64<span class=\"token punctuation\">,</span> Base64<span class=\"token punctuation\">.</span>NO_WRAP<span class=\"token punctuation\">)</span></code></pre><p>The encrypted <code>ByteArray</code> now needs to be turned into the raw string versions, using the same encryption key as was used for the encryption process earlier. We will need to handle a failed decryption in some way, which would mean something had been set up incorrectly or an invalid value was passed in.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">decrypt</span><span class=\"token punctuation\">(</span>encryptedData<span class=\"token operator\">:</span> ByteArray<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> String<span class=\"token operator\">?</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> encryptionKey <span class=\"token operator\">=</span> <span class=\"token function\">generateKey</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">val</span> cell <span class=\"token operator\">=</span> <span class=\"token function\">SecureCell</span><span class=\"token punctuation\">(</span>encryptionKey<span class=\"token punctuation\">,</span> SecureCell<span class=\"token punctuation\">.</span>MODE_SEAL<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token keyword\">try</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">val</span> cellData <span class=\"token operator\">=</span> <span class=\"token function\">SecureCellData</span><span class=\"token punctuation\">(</span>encryptedData<span class=\"token punctuation\">,</span> <span class=\"token keyword\">null</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">val</span> decodedData <span class=\"token operator\">=</span> cell<span class=\"token punctuation\">.</span><span class=\"token function\">unprotect</span><span class=\"token punctuation\">(</span>encryptionContext<span class=\"token punctuation\">,</span> cellData<span class=\"token punctuation\">)</span>\n        <span class=\"token function\">String</span><span class=\"token punctuation\">(</span>decodedData<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span> <span class=\"token keyword\">catch</span> <span class=\"token punctuation\">(</span>error<span class=\"token operator\">:</span> SecureCellException<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        Log<span class=\"token punctuation\">.</span><span class=\"token function\">e</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"EncryptionEngine\"</span></span><span class=\"token punctuation\">,</span> \"Failed <span class=\"token keyword\">to</span> decrypt message<span class=\"token punctuation\">,</span> error<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">null</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Our unencrypted secrets can now be used as they were before. It can be a good practice to decrypt them when they need to be used rather than storing them in an unencrypted state during an app session.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Protecting our API keys and other secrets is a good practice to avoid someone accessing them and causing us harm. This is particularly true if the keys are used for authentication or for accessing our own API that serves up user data. Using various techniques, we have removed the secrets from source control, kept them out of the project, encrypted them and applied protection to our encryption key.</p><p>On top of what has been discussed there are further practices that can be applied, some requiring more significant changes. It is best to evaluate the security needs of a particular application, based on what type of data it uses and the level of security a user would expect. Clearly a banking app will need to be much more security concious than a timer app, however, a good-level of security should be applied regardless to protect access to a user's data.</p>",
			"date_published": "2020-02-16T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/enforcing-type-safety-of-ids-in-kotlin/",
			"url": "https://www.lordcodes.com/articles/enforcing-type-safety-of-ids-in-kotlin/",
			"title": "Enforcing type safety of IDs in Kotlin",
			"content_html": "<p>For codebases with many different entities, most of us will at some point have hit a bug due to the wrong ID being assigned to a property or passed to a function. Why don't we use the type system to give all of our IDs their own type and ensure this never happens again.</p><p>It is very common for objects to need a form of identifier or ID, frequently the reason being to refer to entities when communicating with a remote API or a database. We can easily implement this by giving our classes an ID property with an appropriate type, such as <code>String</code>, <code>UUID</code> or <code>Long</code>. An issue here is that imagine <code>User</code> and <code>Team</code> both have a <code>String</code> ID, it would be perfectly possible to pass a <code>User</code> ID to a function when we were meant to provide a <code>Team</code> ID instead.</p><p>Let's explore the idea of enforcing type safety by giving our IDs their own types.</p><h2 id=\"general-types\" tabindex=\"-1\">General types</h2><p>One option for our IDs is to use the <code>String</code> type, especially if they are in an unexpected format. Another common type of ID is a <a href=\"https://www.rfc-editor.org/rfc/rfc4122.txt\">UUID</a>, an implementation of which is provided by the Java standard library. <code>UUID</code> is designed for storing IDs and is a 128-bit value, which can be easily converted to and from a String.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Team</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> id<span class=\"token operator\">:</span> UUID<span class=\"token punctuation\">,</span> <span class=\"token keyword\">val</span> size<span class=\"token operator\">:</span> Int<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">TeamMember</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> id<span class=\"token operator\">:</span> String<span class=\"token punctuation\">,</span> <span class=\"token keyword\">val</span> name<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span></code></pre><h2 id=\"tiny-type\" tabindex=\"-1\">Tiny type</h2><p>Rather than relying on the general types, we can easily create a dedicated one.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Identifier</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> rawValue<span class=\"token operator\">:</span> UUID<span class=\"token punctuation\">)</span></code></pre><p>If we require different raw types, we can either create extra ID types that contain different raw types or use a single one with a generic type parameter. Using a generic version allows us to have properties or function arguments that require a particular type of ID.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> Identifier<span class=\"token operator\">&lt;</span>RawT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> rawValue<span class=\"token operator\">:</span> RawT<span class=\"token punctuation\">)</span></code></pre><p>We can add helpful extensions to <code>Identifier</code> for use with common raw types, such as pulling out the raw <code>String</code> value:</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">val</span> Identifier<span class=\"token operator\">&lt;</span>UUID<span class=\"token operator\">></span><span class=\"token punctuation\">.</span>uuidString<span class=\"token operator\">:</span> String\n    <span class=\"token keyword\">get</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> rawValue<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><h2 id=\"ensuring-the-correct-type\" tabindex=\"-1\">Ensuring the correct type</h2><p>There are some issues that can appear when using these general types internally. Say <code>Team</code> has a <code>UUID</code> ID and <code>Member</code> has a <code>String</code> ID:</p><ul><li>Every <code>Team</code> ID is a <code>UUID</code>, but not every <code>UUID</code> refers to a valid <code>Team</code>.</li><li>A <code>Member</code> ID could have the same value as the raw <code>String</code> backing a <code>Team</code> ID, even though they refer to different entities.</li></ul><p>Mixing and matching two different IDs that use the same raw type is perfectly valid and not prevented by the compiler. We can do better than this!</p><p>By adding a second generic type parameter to our <code>Identifier</code> we can limit its use for a particular entity.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> Identifier<span class=\"token operator\">&lt;</span>EntityT<span class=\"token punctuation\">,</span> RawT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>\n    <span class=\"token keyword\">val</span> rawValue<span class=\"token operator\">:</span> RawT\n<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Room</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> id<span class=\"token operator\">:</span> Identifier<span class=\"token operator\">&lt;</span>Room<span class=\"token punctuation\">,</span> UUID<span class=\"token operator\">></span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Meeting</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> id<span class=\"token operator\">:</span> Identifier<span class=\"token operator\">&lt;</span>Meeting<span class=\"token punctuation\">,</span> UUID<span class=\"token operator\">></span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">fun</span> <span class=\"token function\">bookMeeting</span><span class=\"token punctuation\">(</span>id<span class=\"token operator\">:</span> Identifier<span class=\"token operator\">&lt;</span>Meeting<span class=\"token punctuation\">,</span> UUID<span class=\"token operator\">></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// ❌ Compile error: Type mismatch.</span>\n<span class=\"token function\">bookMeeting</span><span class=\"token punctuation\">(</span>room<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span></code></pre><p>Due to <code>EntityT</code> not actually being used within <code>Identifier</code> we will likely get a warning about it being unused, which can be ignored using <code>@Suppress(&quot;unused&quot;)</code>.</p><h2 id=\"type-aliases\" tabindex=\"-1\">Type aliases</h2><p>When our codebase has a variety of entities, the number of IDs will grow and we are likely to get fed up with typing out the <code>Identifier</code> signature. We can rely on type aliases to simplify this task. A nice organisation tip is to store these alongside the entity they identify, making them easy to find.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token comment\">// Team.kt</span>\n\n<span class=\"token keyword\">typealias</span> TeamId <span class=\"token operator\">=</span> Identifier<span class=\"token operator\">&lt;</span>Team<span class=\"token punctuation\">,</span> UUID<span class=\"token operator\">></span>\n\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">Team</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> id<span class=\"token operator\">:</span> TeamId<span class=\"token punctuation\">)</span></code></pre><p>Specifying IDs in properties and functions is now so much simpler.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> Team<span class=\"token punctuation\">.</span><span class=\"token function\">inviteMember</span><span class=\"token punctuation\">(</span>id<span class=\"token operator\">:</span> MemberId<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// ❌ Compile error: Type mismatch.</span>\nteam<span class=\"token punctuation\">.</span><span class=\"token function\">inviteMember</span><span class=\"token punctuation\">(</span>team<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// ✅ Compiles.</span>\nteam<span class=\"token punctuation\">.</span><span class=\"token function\">inviteMember</span><span class=\"token punctuation\">(</span>member<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">)</span></code></pre><h2 id=\"alternatives\" tabindex=\"-1\">Alternatives</h2><p>If we wanted to avoid the generic type arguments, we could rely on the brevity of Kotlin data classes and simply have a separate tiny type for each ID.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">MessageId</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> raw<span class=\"token operator\">:</span> UUID<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">ChatId</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> raw<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">PersonId</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> raw<span class=\"token operator\">:</span> Long<span class=\"token punctuation\">)</span></code></pre><p>The advantage is they are significantly simpler due to being just basic data classes, they could even be <a href=\"https://kotlinlang.org/docs/reference/inline-classes.html\">inline classes</a>. A possible downside is that with <code>Identifier</code> we can write code that automatically converts <code>Identifier</code> to other types for tasks such as storing in a <code>Bundle</code> to pass to an <code>Activity</code> or to a format <code>Room</code> can store in a SQLite database. We will have to weigh up the pros and cons of each approach and decide what is best for our particular situation.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>By using a type that enforces type safety of our entity IDs, we can make our model code safer to work on and avoid bugs due to an incorrect ID being used. Our code will also be more readable as when we see an ID we will know which entity it refers to. There may even be ways to extend this solution to make it even more powerful!</p>",
			"date_published": "2020-02-09T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/the-power-of-sealed-classes-in-kotlin/",
			"url": "https://www.lordcodes.com/articles/the-power-of-sealed-classes-in-kotlin/",
			"title": "The power of sealed classes in Kotlin",
			"content_html": "<p>Wouldn't it be great if you could represent a single type that can come in different forms, each able to be constant or carry their own data? If programming in Kotlin, we are in luck as that is exactly what a sealed class is perfect for!</p><p>Enums or enumerated types have existed in many different programming languages for years and allows us to represent a type whose value is taken from a limited set of values. Kotlin takes this concept and evolves into something much more powerful, known as <a href=\"https://kotlinlang.org/docs/reference/sealed-classes.html\">sealed classes</a>. They are a really useful addition to the language, enabling powerful use cases and can help us build some really nice APIs. Let's have a look at how sealed classes can be used, their benefits and some example situations in which they can be the perfect tool for the job.</p><h2 id=\"how\" tabindex=\"-1\">How</h2><p>Both enums and sealed classes allow us to represent a type that can be one value from a set of possibilities. An enum consists of a set of constant values and the instance is assigned one of these constants. Sealed classes instead rely on a set of sub-classes, allowing us to have multiple instances of each sub-class and for them to have their own state.</p><blockquote><p>Sealed class sub-classes can carry their own state</p></blockquote><p>Let's say we have an <code>AuthenticationState</code> that keeps track of which state a user's account is in within our app. The user can be: signed in with a user identifier, signed out with some credentials stored or fully signed out.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">sealed</span> <span class=\"token keyword\">class</span> AuthState <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">SignedIn</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> userGuid<span class=\"token operator\">:</span> UUID<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">AuthState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">StoredCredentials</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> credentials<span class=\"token operator\">:</span> Credentials<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">AuthState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">object</span> SignedOut <span class=\"token operator\">:</span> <span class=\"token function\">AuthState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>By using a sealed class, a property of type <code>AuthenticationState</code> has to have one of the sub-classes assigned to it. We can use a data class to give the sub-class its own properties or an object and make it constant.</p><p>Unlike with an enum, the sub-classes do not need to be kept in the body of the sealed class, only within the same file.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token comment\">// AuthState.kt</span>\n\n<span class=\"token keyword\">sealed</span> <span class=\"token keyword\">class</span> AuthState\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">SignedIn</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> userGuid<span class=\"token operator\">:</span> UUID<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">AuthState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">StoredCredentials</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> credentials<span class=\"token operator\">:</span> Credentials<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">AuthState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">object</span> SignedOut <span class=\"token operator\">:</span> <span class=\"token function\">AuthState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>The way we choose to structure our sealed classes affects how they are referenced, the above examples resulting in <code>AuthState.SignedOut</code> or <code>SignedOut</code>. We can therefore place the sub-classes within the sealed class to create a namespace for our type.</p><h2 id=\"when\" tabindex=\"-1\">When</h2><p>One of the situations sealed classes really stand out is within a <code>when</code> expression. Using <code>when</code> as an expression, assigning or returning the result, allows the compiler to determine if all possible cases have been handled, without needing an <code>else</code> branch.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">onAuthStateChanged</span><span class=\"token punctuation\">(</span>newState<span class=\"token operator\">:</span> AuthState<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">(</span>newState<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">is</span> AuthState<span class=\"token punctuation\">.</span>SignedIn <span class=\"token operator\">-></span> <span class=\"token function\">showSignedIn</span><span class=\"token punctuation\">(</span>newState<span class=\"token punctuation\">.</span>userGuid<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">is</span> AuthState<span class=\"token punctuation\">.</span>StoredCredentials <span class=\"token operator\">-></span> <span class=\"token function\">showSignedIn</span><span class=\"token punctuation\">(</span>newState<span class=\"token punctuation\">.</span>credentials<span class=\"token punctuation\">)</span>\n    AuthState<span class=\"token punctuation\">.</span>SignedOut <span class=\"token operator\">-></span> <span class=\"token function\">showSignedOut</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><blockquote><p>The compiler can determine if all cases have been handled</p></blockquote><p>By using sealed classes within our APIs we can make it really easy for consumers to handle all of the possible states. When used within our own code, if we add an extra sub-class then any <code>when</code> statements used as an expression have to handle it.</p><h2 id=\"view-state\" tabindex=\"-1\">View state</h2><p>In Android apps (or other GUI applications), we need a way to connect the logic that controls our UI to the views themselves. One part of this process may involve modelling the state of the view, such as if it is loading, showing an error or showing data.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">sealed</span> <span class=\"token keyword\">class</span> ViewState\n<span class=\"token keyword\">object</span> LoadingState <span class=\"token operator\">:</span> <span class=\"token function\">ViewState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">PresentingState</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> viewData<span class=\"token operator\">:</span> ContactsViewData<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">ViewState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">ErrorState</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> message<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">ViewState</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>Imagine we are developing a screen that displays a list of contacts loaded from a local database. Our view layer will receive the <code>ViewState</code> and can then render the correct views based on which sub-class of the sealed class is received.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token function\">renderViewState</span><span class=\"token punctuation\">(</span>viewState<span class=\"token operator\">:</span> ViewState<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">(</span>viewState<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n  LoadingState <span class=\"token operator\">-></span> <span class=\"token function\">showLoadingViews</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">is</span> PresentingState <span class=\"token operator\">-></span> <span class=\"token function\">showPresentingViews</span><span class=\"token punctuation\">(</span>viewState<span class=\"token punctuation\">.</span>viewData<span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">is</span> ErrorState <span class=\"token operator\">-></span> <span class=\"token function\">showErrorViews</span><span class=\"token punctuation\">(</span>viewState<span class=\"token punctuation\">.</span>message<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Using a sealed class allows us to update our views for all the possible view states, along with each state carrying a different set of data:</p><ul><li><code>LoadingState</code> can just be an <code>object</code> with no data</li><li><code>PresentingState</code> brings with it <code>ContactsViewData</code> to render the contacts</li><li><code>ErrorState</code> contains an error message to be shown</li></ul><p>Without a sealed class, we would need a class that contains all of the data as nullable properties and an enum to represent which state it was in.</p><h2 id=\"analytics-events\" tabindex=\"-1\">Analytics events</h2><p>We will often need to work out how people are using our apps or verify the effectiveness of certain actions through the use of analytics. This usually boils down to firing off events after specific actions have been taken within the app. These analytics events will be reported in the same way, but may have different properties attached to them, this is a perfect candidate for a sealed class. Code that needs to handle the event can do this easily using a <code>when</code> expression, for example, mapping each event to its map of properties.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">sealed</span> <span class=\"token keyword\">class</span> AnalyticsEvent <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">object</span> AccountCreated <span class=\"token operator\">:</span> <span class=\"token function\">AnalyticsEvent</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">MessageSent</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> conversation<span class=\"token operator\">:</span> Conversation<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">AnalyticsEvent</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">data</span> <span class=\"token keyword\">class</span> <span class=\"token function\">ProfileOpened</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">val</span> participant<span class=\"token operator\">:</span> Participant<span class=\"token punctuation\">)</span> <span class=\"token operator\">:</span> <span class=\"token function\">AnalyticsEvent</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">fun</span> <span class=\"token function\">parameters</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Map<span class=\"token operator\">&lt;</span>Parameter<span class=\"token punctuation\">,</span> String<span class=\"token operator\">></span> <span class=\"token operator\">=</span> <span class=\"token keyword\">when</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        AccountCreated <span class=\"token operator\">-></span> <span class=\"token function\">mapOf</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">is</span> MessageSent <span class=\"token operator\">-></span> <span class=\"token function\">mapOf</span><span class=\"token punctuation\">(</span>\n            Parameter<span class=\"token punctuation\">.</span>PARTICIPANT_COUNT <span class=\"token keyword\">to</span>\n                conversation<span class=\"token punctuation\">.</span>participants<span class=\"token punctuation\">.</span>size<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            Parameter<span class=\"token punctuation\">.</span>IS_ARCHIVED <span class=\"token keyword\">to</span>\n                conversation<span class=\"token punctuation\">.</span>isArchived<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">is</span> ProfileOpened <span class=\"token operator\">-></span> <span class=\"token function\">mapOf</span><span class=\"token punctuation\">(</span>\n            Parameter<span class=\"token punctuation\">.</span>HAS_ACCOUNT <span class=\"token keyword\">to</span>\n                participant<span class=\"token punctuation\">.</span>hasCreatedAccount<span class=\"token punctuation\">.</span><span class=\"token function\">toString</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">enum</span> <span class=\"token keyword\">class</span> Parameter <span class=\"token punctuation\">{</span>\n        HAS_ACCOUNT<span class=\"token punctuation\">,</span>\n        IS_ARCHIVED<span class=\"token punctuation\">,</span>\n        PARTICIPANT_COUNT<span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>We could instead model an analytics event as a simple data class with a name and map of properties. An issue with this approach is it can spread the event names, property names and creation of events all over the codebase. The advantage of the sealed class approach is that we can keep the definition of all our events in one place, ensuring they are correct and that they report the correct properties. It is really great that sealed classes allow us the flexibility to have an <code>AnalyticsEvent</code> type that can be passed around, even though it can come in many different forms.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Sealed classes are a really powerful feature of Kotlin, allowing the flexibility to model a single type that can come in a finite set of different forms. We have only explored a few of the use cases for them, I am sure you will find many more in your codebase!</p>",
			"date_published": "2020-02-02T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/using-kotlin-to-bind-android-views/",
			"url": "https://www.lordcodes.com/articles/using-kotlin-to-bind-android-views/",
			"title": "Using Kotlin to bind Android views",
			"content_html": "<p>When working in the UI layer of an Android app, it won't be long before we need to perform an operation upon one of our views. In order to do this, we first need to retrieve it via <code>findViewById</code>. Although using the API can seem simple, it does introduce a block of boilerplate to our Activities. On top of this the code to bind all the views usually ends up in <code>onCreate</code>, completely separate from the view properties themselves.</p><p>Now that Kotlin has entered the scene with new features we didn't previously have access to it seems like the perfect time to look for a new way of doing things. We will explore how some different approaches, including lazy initialisation and Kotlin Android Extensions, can be used to solve this problem.</p><h2 id=\"the-situation-in-java\" tabindex=\"-1\">The situation in Java</h2><p>To set the scene and to demonstrate how Kotlin can help we first need to look at how these tasks are achieved in Java. To bind views to a field, we would use <code>findViewById</code>, historically casting the resulting view to the correct subclass. For an activity, the views would commonly be bound within <code>onCreate</code>, however, this may be elsewhere if views are retrieved at another time.</p><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">PlanningActivity</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">AppCompatActivity</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token class-name\">TextView</span> planningText<span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">private</span> <span class=\"token class-name\">ImageView</span> appIcon<span class=\"token punctuation\">;</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">protected</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onCreate</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Bundle</span> savedInstanceState<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">onCreate</span><span class=\"token punctuation\">(</span>savedInstanceState<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token function\">setContentView</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">R</span><span class=\"token punctuation\">.</span>layout<span class=\"token punctuation\">.</span>activity_planning<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token comment\">// Before: Needed to cast</span>\n        planningText <span class=\"token operator\">=</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">TextView</span><span class=\"token punctuation\">)</span> <span class=\"token function\">findViewById</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">R</span><span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>planningText<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token comment\">// Now: No longer need to</span>\n        appIcon <span class=\"token operator\">=</span> <span class=\"token function\">findViewById</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">R</span><span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>appIcon<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        planningText<span class=\"token punctuation\">.</span><span class=\"token function\">setText</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The example here is very simple, containing only two views, whereas in reality many different views may need to be accessed. To avoid this repetitive boilerplate <a href=\"https://github.com/JakeWharton/butterknife\">ButterKnife</a> was created, which uses annotation processing to aid the binding of views.</p><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">public</span> <span class=\"token keyword\">class</span> <span class=\"token class-name\">PlanningActivity</span> <span class=\"token keyword\">extends</span> <span class=\"token class-name\">AppCompatActivity</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token annotation punctuation\">@BindView</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">R</span><span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>planningText<span class=\"token punctuation\">)</span> <span class=\"token class-name\">TextView</span> planningText<span class=\"token punctuation\">;</span>\n    <span class=\"token annotation punctuation\">@BindView</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">R</span><span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>appIcon<span class=\"token punctuation\">)</span> <span class=\"token class-name\">ImageView</span> appIcon<span class=\"token punctuation\">;</span>\n\n    <span class=\"token annotation punctuation\">@Override</span>\n    <span class=\"token keyword\">protected</span> <span class=\"token keyword\">void</span> <span class=\"token function\">onCreate</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">Bundle</span> savedInstanceState<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">onCreate</span><span class=\"token punctuation\">(</span>savedInstanceState<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n        <span class=\"token function\">setContentView</span><span class=\"token punctuation\">(</span><span class=\"token class-name\">R</span><span class=\"token punctuation\">.</span>layout<span class=\"token punctuation\">.</span>activity_planning<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        <span class=\"token class-name\">ButterKnife</span><span class=\"token punctuation\">.</span><span class=\"token function\">bind</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n        planningText<span class=\"token punctuation\">.</span><span class=\"token function\">setText</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"Hello!\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><h2 id=\"lazy-in-kotlin\" tabindex=\"-1\">Lazy in Kotlin</h2><p>The Kotlin programming language has many new features and so it feels natural that it may offer a better solution to what we were using before. A new concept in the language is that of <a href=\"https://kotlinlang.org/docs/reference/delegated-properties.html\">delegated properties</a>, specifically the <code>lazy</code> delegated property. The way it works is that when the property is first accessed it will be initialized via the provided function and on future accesses the value will just be returned. This sounds perfect for binding views as the first access can call <code>findViewById</code> and then subsequent calls can just provide the stored view.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> planningText <span class=\"token keyword\">by</span> lazy <span class=\"token punctuation\">{</span>\n    findViewById<span class=\"token operator\">&lt;</span>TextView<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>planningText<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><blockquote><p>A lazy delegated property is initialised on first access</p></blockquote><p>To avoid typing all of this each time we want to bind a view, an extension function on <code>Activity</code> can be created. We can also optimise performance slightly by disabling thread safety, due to the fact that the views will only be accessed from the main UI thread.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">fun</span> <span class=\"token operator\">&lt;</span>ViewT <span class=\"token operator\">:</span> View<span class=\"token operator\">></span> Activity<span class=\"token punctuation\">.</span><span class=\"token function\">bindView</span><span class=\"token punctuation\">(</span><span class=\"token annotation builtin\">@IdRes</span> idRes<span class=\"token operator\">:</span> Int<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> Lazy<span class=\"token operator\">&lt;</span>ViewT<span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">lazy</span><span class=\"token punctuation\">(</span>LazyThreadSafetyMode<span class=\"token punctuation\">.</span>NONE<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        findViewById<span class=\"token operator\">&lt;</span>ViewT<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>idRes<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> PlanningActivity <span class=\"token operator\">:</span> <span class=\"token function\">AppCompatActivity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> planningText <span class=\"token keyword\">by</span> bindView<span class=\"token operator\">&lt;</span>TextView<span class=\"token operator\">></span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>planningText<span class=\"token punctuation\">)</span>\n    <span class=\"token comment\">// or</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> planningText<span class=\"token operator\">:</span> TextView <span class=\"token keyword\">by</span> <span class=\"token function\">bindView</span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>id<span class=\"token punctuation\">.</span>planningText<span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>We now have a succinct and clear call site, with full control over the view binding and no generated code required. As <code>bindView</code> is essentially a wrapper around <code>findViewById</code> it can be applied elsewhere in the codebase, beyond just in <code>Activity</code>.</p><h2 id=\"lazy-elsewhere\" tabindex=\"-1\">Lazy elsewhere</h2><p>Applying to views, such as in a <code>RecyclerView.ViewHolder</code> is as simple as creating a similar extension function to give us access to the same API we had within Activities.</p><p>Where our technique encounters some issues is when used within a <code>Fragment</code> due to differences in their lifecycle. Without alterations the lazy property can refer to an old view instance after the <code>Fragment</code> view has been recreated. We can either avoid lazy view binding in Fragments or put together a solution using the Lifecycle Architecture Component. By creating our own version of <code>Lazy</code> we can reset the stored value in <code>onDestroyView</code>, causing the next access to call <code>findViewById</code> again. An example implementation demonstrating this idea can be <a href=\"https://github.com/lordcodes/lordcodes-samples/blob/master/android/using-lazy-in-kotlin-to-bind-android-views/app/src/main/kotlin/com/lordcodes/lazyviewbindingarticle/lazyfragment/FragmentExt.kt\">found within the sample code</a> for the article.</p><h2 id=\"synthetic-properties\" tabindex=\"-1\">Synthetic properties</h2><p>As an alternative to implementing our own solution, especially if the situation with Fragments makes the lazy binding approach undesirable, we can use the <a href=\"https://kotlinlang.org/docs/tutorials/android-plugin.html\">Kotlin Android Extensions</a>. The plugin automatically generates properties that match the IDs of the views in our layout file. Views no longer need to be stored manually as properties, as they are instead accessed via synthetic properties generated by the plugin.</p><blockquote><p>Automatically generated properties that bind to our views</p></blockquote><p>We first need to apply the plugin within our Gradle configuration.</p><p><strong>build.gradle</strong></p><pre class=\"language-gradle\"><code class=\"language-gradle\"><span class=\"token keyword\">apply</span> <span class=\"token keyword\">plugin</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'kotlin-android-extensions'</span></code></pre><p><strong>build.gradle.kts</strong></p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token function\">apply</span><span class=\"token punctuation\">(</span>plugin <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"kotlin-android-extensions\"</span></span><span class=\"token punctuation\">)</span></code></pre><p>Once applied the plugin will generate synthetic properties for us to access views that are specified within our layout XML files, with names matching the IDs. To access the properties we need to add an import statement for each layout file. It is recommended to use the star syntax for the import, with Android Studio already having this specified within the default code style settings. The IDE should also add the import automatically when you try to reference one of the properties.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">import</span> kotlinx<span class=\"token punctuation\">.</span>android<span class=\"token punctuation\">.</span>synthetic<span class=\"token punctuation\">.</span>main<span class=\"token punctuation\">.</span>activity_planning<span class=\"token punctuation\">.</span><span class=\"token operator\">*</span>\n\n<span class=\"token keyword\">class</span> PlanningActivity <span class=\"token operator\">:</span> <span class=\"token function\">AppCompatActivity</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">override</span> <span class=\"token keyword\">fun</span> <span class=\"token function\">onCreate</span><span class=\"token punctuation\">(</span>savedInstanceState<span class=\"token operator\">:</span> Bundle<span class=\"token operator\">?</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">super</span><span class=\"token punctuation\">.</span><span class=\"token function\">onCreate</span><span class=\"token punctuation\">(</span>savedInstanceState<span class=\"token punctuation\">)</span>\n\n        <span class=\"token function\">setContentView</span><span class=\"token punctuation\">(</span>R<span class=\"token punctuation\">.</span>layout<span class=\"token punctuation\">.</span>activity_planning<span class=\"token punctuation\">)</span>\n        planningText<span class=\"token punctuation\">.</span>text <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Hello\"</span></span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The plugin comes with other features such as applying to other custom containers and customising the view caching. Any features that are still considered experimental can be enabled within our Gradle configuration. Please find all the details of the other features on the <a href=\"https://kotlinlang.org/docs/tutorials/android-plugin.html\">plugin website</a>.</p><pre class=\"language-gradle\"><code class=\"language-gradle\">androidExtensions <span class=\"token punctuation\">{</span>\n  experimental <span class=\"token operator\">=</span> <span class=\"token boolean\">true</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Using Kotlin Android Extensions is a very clean approach, requiring practically no extra code. To previous users of ButterKnife it feels like an evolution to that approach. As with any potential solution it is best to try it out, see how it works and whether it fits with all the use cases a particular project has.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>When this article was originally written I recommended the lazy property approach due to us being able to strike a great balance between brevity, avoidance of boilerplate and reducing reliance on generated code. Since this time I have found that my preferred solution has shifted towards the Kotlin Android Extensions plugin due to its simplicity and not having to worry if there will be issues with lazy binding in situations such as that of Fragments.</p>",
			"date_published": "2019-01-30T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/android-signing-using-gradle-properties/",
			"url": "https://www.lordcodes.com/articles/android-signing-using-gradle-properties/",
			"title": "Android signing keystore details from Gradle properties",
			"content_html": "<p>We may want to keep our Android project keystore details out of our source code and Git by passing them in. Aided by a handy function, these can be referenced from Gradle in Groovy or Kotlin.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>gradle<span class=\"token punctuation\">.</span>api<span class=\"token punctuation\">.</span>Project\n\n<span class=\"token keyword\">fun</span> Project<span class=\"token punctuation\">.</span><span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span>name<span class=\"token operator\">:</span> String<span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> String <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">findProperty</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">)</span> <span class=\"token keyword\">as</span> String<span class=\"token operator\">?</span> <span class=\"token operator\">?:</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"\"</span></span>\n<span class=\"token punctuation\">}</span>\n\nandroid <span class=\"token punctuation\">{</span>\n  signingConfigs <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">create</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"upload\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      storeFile <span class=\"token operator\">=</span> <span class=\"token function\">file</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"upload.keystore\"</span></span><span class=\"token punctuation\">)</span>\n      storePassword <span class=\"token operator\">=</span> <span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"UPLOAD_STORE_PASSWORD\"</span></span><span class=\"token punctuation\">)</span>\n      keyAlias <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"keyname\"</span></span>\n      keyPassword <span class=\"token operator\">=</span> <span class=\"token function\">propertyOrEmpty</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"UPLOAD_KEY_PASSWORD\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2019-01-27T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/adding-continuous-integration-android/",
			"url": "https://www.lordcodes.com/articles/adding-continuous-integration-android/",
			"title": "Adding Continuous Integration to your Android project",
			"content_html": "<p>When working on a software project, particularly in a team, a common workflow involves branching from the main branch, often master or develop. The created branch is where changes for a particular feature or issue are applied. One way of managing this branch would involve committing all work for a large feature to this branch and then merging it back once it has been completed. This means the branch lives for a relatively long time and we will likely find the integration process to be a painful process.</p><p>Continuous Integration, commonly referred to as CI, is a popular development practice that instead involves integrating changes back into the main branch regularly. By integrating regularly the aim is that the cost of doing so will go down and errors will be detected more quickly. An important part of this process is that before changes are merged, the code is automatically built and tested. By testing before the merge instead of afterwards, integration issues are visible earlier and issues can hopefully be fixed more easily.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/LGKkzI87Wg-1000.webp 1000w\"><img src=\"https://www.lordcodes.com/img/LGKkzI87Wg-1000.jpeg\" alt=\"Continuous Integration diagram\" width=\"1000\" height=\"440\"></picture></p><p>Many people will agree that CI provides many benefits in a team environment, including in-house teams and open source projects with many different contributors. What is spoken about less often are the benefits of using CI in a solo environment. By having CI building and testing our code before it is merged, we can integrate code more safely and monitor it over time.</p><h2 id=\"available-solutions\" tabindex=\"-1\">Available solutions</h2><p>In order to build and test code automatically, it is a good idea to have the process running on a CI server of some kind. This server monitors the codebase for changes, such as via a Pull Request using web-hooks, and then triggers the test suite to be executed. By ensuring the CI server is separate to the development machines verifies that it builds correctly in a clean and consistent environment.</p><blockquote><p>A pull request can automatically trigger a test run</p></blockquote><p>When it comes to setting up and running a CI server, there are a huge number of services to choose from. We will have a look at a few that work differently to give an idea of what is available.</p><p><a href=\"https://circleci.com/\"><strong>Circle CI</strong></a> is a cloud-based service that uses either Linux or MacOS virtual machines as the build environment. For Android, Linux is the best option due to the pricing being much more favourable with a free tier. Configuring the build jobs involves a YAML file within the project, resulting in a process that is very customisable.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/Lsr2yAgao5-300.webp 300w\"><img src=\"https://www.lordcodes.com/img/Lsr2yAgao5-300.jpeg\" alt=\"Circle CI logo\" width=\"300\" height=\"246\"></picture></p><p><a href=\"https://bitrise.io\"><strong>Bitrise</strong></a> is similar to Circle CI in that it is a cloud-based service, however, it is tailored to the individual needs of mobile development. This means it has many mobile specific integrations, including deploying to Google Play alongside services such as TestFairy and Firebase Test Lab. As with Circle CI there is a free tier, although it is fairly limited in terms of build minutes allowed. Configuring the build jobs can be done either via a YAML file in the project or using the workflow editor directly within the web UI, giving an increased level of flexibility.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/DeEkOx5Fmj-430.webp 430w\"><img src=\"https://www.lordcodes.com/img/DeEkOx5Fmj-430.jpeg\" alt=\"Bitrise logo\" width=\"430\" height=\"164\"></picture></p><p><a href=\"https://www.jenkins.io\"><strong>Jenkins</strong></a> is the leading self-hosted automation server that we install, configure and maintain ourselves on our own hardware or cloud infrastructure. Jenkins is perfect for people who want to maintain the full CI set up themselves. It is incredibly customisable, where we can essentially make it do whatever we want, boasting a huge number of plugins and integrations from the community. It does come at the cost of doing all this, where the other cloud-based solutions are managed for you.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/dc0yTPuWkn-490.webp 490w\"><img src=\"https://www.lordcodes.com/img/dc0yTPuWkn-490.jpeg\" alt=\"Jenkins logo\" width=\"490\" height=\"185\"></picture></p><p>There are many other CI solutions that haven't been mentioned here including: <a href=\"https://www.travis-ci.com\">Travis CI</a>, <a href=\"https://codemagic.io/start/\">CodeMagic</a>, <a href=\"https://about.gitlab.com/solutions/continuous-integration/\">GitLab CI</a>, <a href=\"https://www.jetbrains.com/teamcity/\">TeamCity</a> and <a href=\"https://www.atlassian.com/software/bitbucket/features/pipelines\">Bitbucket Pipelines</a>.</p><p>The best solution isn't the same for everyone. The best solution depends on individual requirements, the features we want and also personal preference. To explore the process of setting up CI, we will look at getting a simple workflow running in both Circle CI and Bitrise via the web UI, for comparison.</p><h2 id=\"circle-ci\" tabindex=\"-1\">Circle CI</h2><p>Once our Circle CI account has been created and integrated with our source control, such as GitHub or Bitbucket, we can start creating our CI config. For Circle CI, this needs to be a YAML file at <code>.circleci/config.yml</code>.</p><pre class=\"language-yaml\"><code class=\"language-yaml\"><span class=\"token key atrule\">version</span><span class=\"token punctuation\">:</span> <span class=\"token number\">2.0</span>\n\n<span class=\"token key atrule\">jobs</span><span class=\"token punctuation\">:</span>\n  <span class=\"token key atrule\">build</span><span class=\"token punctuation\">:</span>\n    <span class=\"token key atrule\">working_directory</span><span class=\"token punctuation\">:</span> ~/workspace\n    <span class=\"token key atrule\">docker</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">image</span><span class=\"token punctuation\">:</span> circleci/android<span class=\"token punctuation\">:</span>api<span class=\"token punctuation\">-</span><span class=\"token number\">28</span>\n\n    <span class=\"token key atrule\">steps</span><span class=\"token punctuation\">:</span>\n      <span class=\"token punctuation\">-</span> checkout\n\n      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">run</span><span class=\"token punctuation\">:</span>\n          <span class=\"token key atrule\">name</span><span class=\"token punctuation\">:</span> Run tests\n          <span class=\"token key atrule\">command</span><span class=\"token punctuation\">:</span> ./gradlew lintDebug testDebugUnitTest\n\n      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">store_artifacts</span><span class=\"token punctuation\">:</span>\n          <span class=\"token key atrule\">path</span><span class=\"token punctuation\">:</span> app/build/reports\n          <span class=\"token key atrule\">destination</span><span class=\"token punctuation\">:</span> reports\n      <span class=\"token punctuation\">-</span> <span class=\"token key atrule\">store_test_results</span><span class=\"token punctuation\">:</span>\n          <span class=\"token key atrule\">path</span><span class=\"token punctuation\">:</span> app/build/test<span class=\"token punctuation\">-</span>results</code></pre><ul><li>We start off by requesting Circle CI 2.0.</li><li>We can next set up our jobs, which in this simple example consist of a single job that runs Android Lint and our unit tests.</li><li>The first thing our job needs to do is configure the working directory and the image to use for our build environment. The working directory will be needed to do more advanced customisations such as sharing a workspace between steps in a workflow.</li><li>Within the build job definition, we can list the steps to take, starting with checking out the code, running our tests and archiving the test results.</li></ul><p>This example only covers the very basics and there is much more we can do with our configuration. An example showing a more advanced workflow including caching and sharing the workspace between workflow steps <a href=\"https://gist.github.com/lordcodes/65101116156a44b075ce2a126313b9c6\">can be found as a gist</a>.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/PQfS5_G_cR-1000.webp 1000w\"><img src=\"https://www.lordcodes.com/img/PQfS5_G_cR-1000.jpeg\" alt=\"Circle CI workflow\" width=\"1000\" height=\"700\"></picture></p><h2 id=\"bitrise\" tabindex=\"-1\">Bitrise</h2><p>After creating our Bitrise account, we can add our app to Bitrise by following through the full set up wizard. Bitrise is specifically designed for mobile, the detailed wizard helping with pretty much all of the heavy lifting. Once complete and on the dashboard page for our project, the navigation banner should be visible, giving us access to all of the customisation we need.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/BKEuGXkWDY-1440.webp 1440w\"><img src=\"https://www.lordcodes.com/img/BKEuGXkWDY-1440.jpeg\" alt=\"Bitrise navigation banner\" width=\"1440\" height=\"120\"></picture></p><p>Entering into the 'workflow' area, we will be able to fine tune the default generated workflow as well as add any extra workflows we will need. Each workflow can be <a href=\"https://devcenter.bitrise.io/en/builds/starting-builds/triggering-builds-automatically.html\">triggered at different times</a>, so we could have one that runs for pull requests and another for tagged commits as an example.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/ZMKfJyy0G0-1440.webp 1440w\"><img src=\"https://www.lordcodes.com/img/ZMKfJyy0G0-1440.jpeg\" alt=\"Bitrise workflow\" width=\"1440\" height=\"510\"></picture></p><p>For our build we will need:</p><ol><li><strong>Activate SSH key</strong> to set up SSH access to our source code.</li><li><strong>Git clone repository</strong> to retrieve our source code.</li><li><strong>Install missing Android SDK components</strong> to ensure the Android SDK is available and updated.</li><li><strong>Gradle Runner</strong> to run a Gradle task of our choice, where we should set the 'Gradle task to run' to <code>lintDebug</code>.</li><li><strong>Gradle Unit Test</strong> to run unit tests with Gradle, where we should set the 'Test task' to <code>testDebugUnitTest</code>.</li><li><strong>Deploy to Bitrise.io</strong> to deploy files and attach them to the Bitrise build page.</li></ol><p>This covers a basic workflow that matches the one we created for Circle CI above. More advanced workflows can easily be put together using the <a href=\"https://bitrise.io/integrations\">many steps available</a>, which are open source and <a href=\"https://github.com/bitrise-io/bitrise-steplib/tree/master/steps\">viewable on GitHub</a>.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Both Circle CI and Bitrise are very powerful and capable CI tools that apply well to Android development. Both solutions also work well for iOS development, allowing teams that develop for both platforms to use the same tool and subscription.</p><p><strong>Circle CI</strong> has a more generous free tier in terms of usage, is highly customisable and will be very familiar with those used to configuring CI with a YAML file. <strong>Bitrise</strong> has more mobile specific plugins available out-of-the-box, allows configuration via the web UI and has a much more user-friendly interface.</p><p>It is important to find the right CI tool for the job by trying out the different options. When it comes to CI everyone will have a personal preference and this plays an important role in the decision of which one to use. It is even worth thinking about using CI for solo projects, although there is a set up and maintenance cost, it is still very valuable knowing that the project builds and that all tests are passing.</p>",
			"date_published": "2019-01-24T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/kotlin-source-directory-gradle-kotlin-dsl/",
			"url": "https://www.lordcodes.com/articles/kotlin-source-directory-gradle-kotlin-dsl/",
			"title": "Set up Kotlin source directory from Gradle Kotlin DSL",
			"content_html": "<p>When converting Android Gradle files from Groovy to Kotlin, one thing that may not be clear is how to keep Kotlin sources within <code>src/main/kotlin</code>. We simply need to get the source sets by name and call <code>java.srcDirs()</code> as a function call. Works like a dream!</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">sourceSets <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">getByName</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"main\"</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>java<span class=\"token punctuation\">.</span><span class=\"token function\">srcDirs</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"src/main/kotlin\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">getByName</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"test\"</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>java<span class=\"token punctuation\">.</span><span class=\"token function\">srcDirs</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"src/test/kotlin\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token function\">getByName</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"androidTest\"</span></span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>java<span class=\"token punctuation\">.</span><span class=\"token function\">srcDirs</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"src/androidTest/kotlin\"</span></span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2019-01-20T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/file-extensions-and-utis/",
			"url": "https://www.lordcodes.com/articles/file-extensions-and-utis/",
			"title": "Dealing with file extensions and Uniform Type Identifiers",
			"content_html": "<p>There are different ways of representing a type of file, two popular ones being file extensions and another being Uniform Type Identifiers (UTIs) from the UIKit APIs. When working with a UIKit API such as <code>UIDocumentPickerViewController</code> we may need to distinguish between these types.</p><p>We can create independent types to hold file extensions and type identifiers, this makes it really clear which one is required for a particular piece of functionality.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">FileExtension</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">let</span> rawValue<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">asTypeIdentifier</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">TypeIdentifier</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">let</span> identifierCreated <span class=\"token operator\">=</span> <span class=\"token class-name\">UTTypeCreatePreferredIdentifierForTag</span><span class=\"token punctuation\">(</span>\n            <span class=\"token constant\">kUTTagClassFilenameExtension</span><span class=\"token punctuation\">,</span> rawValue <span class=\"token keyword\">as</span> <span class=\"token class-name\">NSString</span><span class=\"token punctuation\">,</span> <span class=\"token nil constant\">nil</span>\n        <span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">if</span> <span class=\"token keyword\">let</span> typeIdentifier <span class=\"token operator\">=</span> identifierCreated<span class=\"token operator\">?</span><span class=\"token punctuation\">.</span><span class=\"token function\">takeRetainedValue</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token keyword\">return</span> <span class=\"token class-name\">TypeIdentifier</span><span class=\"token punctuation\">(</span>rawValue<span class=\"token punctuation\">:</span> typeIdentifier <span class=\"token keyword\">as</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">return</span> <span class=\"token class-name\">TypeIdentifier</span><span class=\"token punctuation\">(</span>rawValue<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"public.data\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">struct</span> <span class=\"token class-name\">TypeIdentifier</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">let</span> rawValue<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2019-01-18T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/swift-logging-with-oslog/",
			"url": "https://www.lordcodes.com/articles/swift-logging-with-oslog/",
			"title": "Clear and searchable logging in Swift with OSLog",
			"content_html": "<p>When it comes to logging in Swift and iOS applications in particular, the APIs that first come to mind might be <code>print</code> and <code>NSLog</code>. More recently, however, Apple has introduced a new standard for logging in the form of <a href=\"https://developer.apple.com/documentation/os/logging\">unified logging</a>, accessed via <code>OSLog</code>. It is the current recommended way of logging, providing an efficient way to capture information across our applications.</p><p>Unified logging provides a number of improvements over previous techniques and also some differences to what we are used to.</p><ol><li>Each message can be logged at an appropriate level, including: default, error, debug and info. They affect how messages are displayed to us and persisted.</li><li>Messages are grouped within subsystems and categories to enable efficient searching and filtering.</li><li>There is no need to wrap log statements in conditionals, due to the system being designed for performance and logs being rendered only when read.</li><li>User privacy is carefully respected, with dynamic string content needing to be explicitly marked as public, else they are redacted in any logs.</li></ol><h2 id=\"let's-get-logging\" tabindex=\"-1\">Let's get logging</h2><p>Using unified logging from Swift is as simple as using the <code>os_log</code> function, which we will quickly notice takes a <code>StaticString</code> as an argument rather than a regular <code>String</code>. The easiest way to log messages, is to place the <code>String</code> constant directly in the function call. Extracting the message to a property is possible, however, we will need to define it's type as <code>StaticString</code>.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"User signed in\"</span></span><span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">let</span> errorMessage<span class=\"token punctuation\">:</span> <span class=\"token class-name\">StaticString</span> <span class=\"token operator\">=</span> <span class=\"token string-literal\"><span class=\"token string\">\"404 - NOT FOUND\"</span></span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span>errorMessage<span class=\"token punctuation\">)</span></code></pre><p>Due to the <code>StaticString</code> requirement, instead of using string interpolation we will need to use format arguments. This may feel jarring initially, however, it isn't too hard to adapt to and it provides benefits to user privacy that we will discuss a bit later on. We have access to all of the <a href=\"https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFStrings/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265\">standard format arguments</a>, as well as a number of <a href=\"https://developer.apple.com/documentation/os/logging#1682416\">extra value type decoders</a>. The idea is that the logging system handles as much formatting for you as possible, to make the system even more efficient.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">let</span> responseCode <span class=\"token operator\">=</span> <span class=\"token string-literal\"><span class=\"token string\">\"404 - NOT FOUND\"</span></span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: %@\"</span></span><span class=\"token punctuation\">,</span> responseCode<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">let</span> logMessage <span class=\"token operator\">=</span> <span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: </span><span class=\"token interpolation-punctuation punctuation\">\\(</span><span class=\"token interpolation\">responseCode</span><span class=\"token interpolation-punctuation punctuation\">)</span><span class=\"token string\">\"</span></span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"%@\"</span></span><span class=\"token punctuation\">,</span> logMessage<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\">// error: cannot convert value of type 'String'</span>\n<span class=\"token comment\">// to expected argument type 'StaticString'</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: </span><span class=\"token interpolation-punctuation punctuation\">\\(</span><span class=\"token interpolation\">responseCode</span><span class=\"token interpolation-punctuation punctuation\">)</span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span></code></pre><h2 id=\"it's-good-to-be-organised\" tabindex=\"-1\">It's good to be organised</h2><p>Calls to <code>os_log</code> can specify an <code>OSLog</code> to use, containing a specific subsystem and category. This information is invaluable when filtering, searching and trying to understand our logs later. When the log argument isn't specified a default one is used, which has no subsystem or category configured.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">let</span> uiLog <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>subsystem<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"com.lordcodes.chat.ChatApp\"</span></span><span class=\"token punctuation\">,</span> category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"UI\"</span></span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Contact selected\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> uiLog<span class=\"token punctuation\">)</span>\n\n<span class=\"token keyword\">let</span> networkLog <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>\n    subsystem<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"com.lordcodes.chat.ChatKit\"</span></span><span class=\"token punctuation\">,</span>\n    category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Network\"</span></span>\n<span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: %@\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> networkLog<span class=\"token punctuation\">,</span> responseCode<span class=\"token punctuation\">)</span></code></pre><p>The subsystem groups all the logs for a particular app or module, allowing us to filter for all of our own logs. From evaluating Apple's logs, the convention for subsystem is a reverse domain style, such as the Bundle Identifier of the app or framework itself. If the app is modularised into frameworks, it is a good idea to use the Bundle Identifier of the framework to split logs into their corresponding components.</p><p>Categories are used to group logs into related areas, to help us narrow down the scope of log messages. The convention for categories is to use human-readable names like <code>UI</code> or <code>User</code>. We could group logs into layers across multiple subsystems or features, such as <code>Network</code> or <code>Contacts</code>. Alternatively, we could group all the logs for a particular class, such as <code>Contacts Repository</code>. It would be perfectly acceptable to combine both approaches in the same project, we should simply use the most appropriate categories to allow us to understand the context of the project's log messages.</p><p>We can add our different categories and subsystems as an extension of <code>OSLog</code>, making them easily accessible across the app. Storing them in one place avoids creating <code>OSLog</code> instances all over the codebase and helps keep the different categories in use nicely organised.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">OSLog</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">var</span> subsystem <span class=\"token operator\">=</span> <span class=\"token class-name\">Bundle</span><span class=\"token punctuation\">.</span>main<span class=\"token punctuation\">.</span>bundleIdentifier<span class=\"token operator\">!</span>\n\n    <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> ui <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>subsystem<span class=\"token punctuation\">:</span> subsystem<span class=\"token punctuation\">,</span> category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"UI\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> network <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>subsystem<span class=\"token punctuation\">:</span> subsystem<span class=\"token punctuation\">,</span> category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Network\"</span></span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Contact selected\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>ui<span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: %@\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>network<span class=\"token punctuation\">,</span> responseCode<span class=\"token punctuation\">)</span></code></pre><h2 id=\"logging-levels\" tabindex=\"-1\">Logging levels</h2><p>The unified logging system employs a set of different logging levels at which we can target different types of messages. The levels control how messages are displayed to us, how and when they are persisted and whether they are captured in different environments. How the system handles each level can even be customised through the <a href=\"https://developer.apple.com/documentation/os/logging#2878594\">command-line on our machine</a>. It is a good idea to use the most appropriate logging level for each message, to get the most we can out of the logging system.</p><p><strong>Default</strong>: To capture anything that might result in a failure and essentially a fall-back if no other level seems appropriate. Unless changed, messages are stored in memory buffers and persisted when they fill up.</p><p><strong>Info</strong>: To capture anything that may be useful, but is not directly used to diagnose or troubleshoot errors. Unless changed, no persistence is used, messages are just stored in memory buffers and purged as they fill up.</p><p><strong>Debug</strong>: To capture information during development to diagnose a particular issue, whilst actively debugging. They aren't captured unless enabled by a configuration change.</p><p><strong>Error</strong>: To capture application errors and failures, in particular anything critical. Messages are always persisted, to ensure they are no lost.</p><p><strong>Fault</strong>: To capture system-level or multi-process errors only, likely not of use in our app code. As with the error level, messages are always persisted.</p><p>Logging at each level is as simple as specifying the corresponding <code>OSLogType</code> as an argument to the <code>os_log</code> call.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Contact selected\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>ui<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Saving contact failed\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>database<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>error<span class=\"token punctuation\">)</span></code></pre><h2 id=\"user-privacy\" tabindex=\"-1\">User privacy</h2><p>To ensure private user data is not accidentally persisted to application logs, which may be shared with other people, the unified logging system has a public and private argument process. By default, only scalar (boolean, integer) values are collected and dynamic strings or complex dynamic objects are redacted. If it is necessary, dynamic string arguments may be declared public and scalar arguments could also be declared private.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Contact %ld selected\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Contact %{private}ld selected\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: %@\"</span></span><span class=\"token punctuation\">,</span> responseCode<span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"HTTP response: %{public}@\"</span></span><span class=\"token punctuation\">,</span> responseCode<span class=\"token punctuation\">)</span></code></pre><p>It is important we resist making all arguments public, as it could easily result in private company or user data being exposed within device logs.</p><h2 id=\"reading-logs\" tabindex=\"-1\">Reading logs</h2><p>Whilst the debugger is attached, log messages will be shown in the Xcode console. The best way to read our logs, however, is with the Console MacOS application. Here we will be able to sort, filter and search our logs, as well as view them more easily.</p><ul><li>Display logs in a table, making each piece of data easy to read</li><li>Search and filter by subsystem and category</li><li>Show and hide different fields for each log message</li><li>Turn on and off debug and info level messages</li><li>Save search patterns to access them more easily in the future</li></ul><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Unified logging is a promising and powerful logging solution, especially when it comes to performance and filtering your log messages. Initially it might seem like it has quirks or differences to what you may be used to from <code>NSLog</code> and <code>print</code>. After looking a bit more and providing <code>os_log</code> with subsystems, categories and making good use of logging levels, you will find it makes working with logs significantly easier. If you want more log coverage with better performance, you can ditch <code>NSLog</code> and <code>print</code> statements and start integrating <code>os_log</code> into your apps.</p><blockquote><p>OSLog is Apple's current recommended logging approach</p></blockquote>",
			"date_published": "2019-01-14T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/simpler-categories-when-using-oslog/",
			"url": "https://www.lordcodes.com/articles/simpler-categories-when-using-oslog/",
			"title": "Simpler categories when using OSLog",
			"content_html": "<p>Organised logging in Swift that can be searched is simple thanks to the built-in <code>os_log</code>. By storing our categories as an extension on <code>OSLog</code> we can access them using a short syntax.</p><p>This makes categories so much easier to specify and helps with auto-completion!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">OSLog</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> logAuthentication <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>\n        subsystem<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"com.myapp.App\"</span></span><span class=\"token punctuation\">,</span>\n        category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Auth\"</span></span>\n    <span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> logDatabase <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>\n        subsystem<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"com.myapp.App\"</span></span><span class=\"token punctuation\">,</span>\n        category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Database\"</span></span>\n    <span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> logNetwork <span class=\"token operator\">=</span> <span class=\"token class-name\">OSLog</span><span class=\"token punctuation\">(</span>\n        subsystem<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"com.myapp.App\"</span></span><span class=\"token punctuation\">,</span>\n        category<span class=\"token punctuation\">:</span> <span class=\"token string-literal\"><span class=\"token string\">\"Network\"</span></span>\n    <span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"User signed in: %@\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>logAuthentication<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span><span class=\"token keyword\">default</span><span class=\"token punctuation\">,</span> email<span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Chat messages sync complete\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>logNetwork<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>info<span class=\"token punctuation\">)</span>\n<span class=\"token function\">os_log</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Chat messages saved successfully\"</span></span><span class=\"token punctuation\">,</span> log<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>logDatabase<span class=\"token punctuation\">,</span> type<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>debug<span class=\"token punctuation\">)</span></code></pre>",
			"date_published": "2019-01-10T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/share-xcode-file-templates/",
			"url": "https://www.lordcodes.com/articles/share-xcode-file-templates/",
			"title": "Create Xcode file templates and share them with your team",
			"content_html": "<p>Something all Xcode users will be familiar with is the process of creating new files. When the new file command is triggered, we are presented with a window containing a selection of templates to base our new file upon. These new templates often contain lines of code we immediately delete or code that needs to be changed to fit into our preferred style.</p><p>Many people may be unaware that instead of relying solely on the provided templates, we can create our own and have Xcode present them to us. This can simplify the process of creating new files and allow them to match more specific requirements.</p><p>The process of creating templates can seem a bit confusing at first, but the end result can be really useful. We are going to explore the process of writing our own Xcode file templates, before delving into how we might go about sharing these with other developers on a particular project.</p><h2 id=\"creating-a-template\" tabindex=\"-1\">Creating a template</h2><p>When Xcode launches, it looks for file templates within a specific location: <code>~/Library/Developer/Xcode/Templates/File Templates</code>. To get started, we need to create a directory within here that will house all of our file templates.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">mkdir</span> <span class=\"token parameter variable\">-p</span> ~/Library/Developer/Xcode/Templates/File<span class=\"token punctuation\">\\</span> Templates/Custom</code></pre><p>Within this directory, a quick way to get started is by copying one of the built-in templates and then altering it. They can be found within the Xcode application bundle, with a good option for Swift-based templates being the one for a new Swift file, <code>Source/Swift File.xctemplate</code>.</p><pre class=\"language-shell\"><code class=\"language-shell\">/Applications/Xcode.app/Contents/\n  <span class=\"token operator\">></span> Developer/\n    <span class=\"token operator\">></span> Library/\n      <span class=\"token operator\">></span> Xcode/\n        <span class=\"token operator\">></span> Templates/\n          <span class=\"token operator\">></span> File Templates/</code></pre><p>After copying the files, we find the <code>xctemplate</code> contains 4 different files.</p><ul><li><code>TemplateIcon.png</code> and <code>TemplateIcon@2x.png</code> are the thumbnails that are presented within the new file window. We could use these for all of our Swift templates or create specific ones of our own.</li><li><code>TemplateInfo.plist</code> is where we configure our template.</li><li><code>___FILEBASENAME___.swift</code> contains the Swift source that forms the basis of the template.</li></ul><p>We will start by creating a template for a new Swift struct, called <code>Swift Struct.xctemplate</code>, that is based upon the <code>Swift File.xctemplate</code> mentioned above.</p><p><strong>→ TemplateInfo.plist</strong></p><p>Within the property file we can change the <code>Description</code> and <code>Summary</code> keys to clearly describe the template within Xcode.</p><pre class=\"language-xml\"><code class=\"language-xml\"><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>key</span><span class=\"token punctuation\">></span></span>Description<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>key</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>string</span><span class=\"token punctuation\">></span></span>A Swift struct.<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>string</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>key</span><span class=\"token punctuation\">></span></span>Summary<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>key</span><span class=\"token punctuation\">></span></span>\n<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;</span>string</span><span class=\"token punctuation\">></span></span>A Swift struct.<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;/</span>string</span><span class=\"token punctuation\">></span></span></code></pre><p><strong>→ ___FILEBASENAME___.swift</strong></p><p>By calling the file <code>___FILEBASENAME___.swift</code>, the resulting Swift file will be named according to what is entered into the new file window. This same argument can be used within the template using <code>___FILEBASENAMEASIDENTIFIER___</code>. This means that if we enter <code>Contact</code> into the new file window, the generated file will be <code>Contact.swift</code>, containing the struct <code>Contact</code>.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">struct</span> <span class=\"token constant\">___FILEBASENAMEASIDENTIFIER___</span> <span class=\"token punctuation\">{</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Once completing the template, starting up Xcode and requesting a new file, we can find our template being offered within a section called 'Custom'. The name of the section is controlled by the directory name we used within <code>~/Library/Developer/Xcode/Templates/File Templates</code>.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/yi8z7Ti_rI-1470.webp 1470w\"><img src=\"https://www.lordcodes.com/img/yi8z7Ti_rI-1470.jpeg\" alt=\"Xcode new file window showing template\" title=\"Our new template shown within Xcode\" width=\"1470\" height=\"592\"></picture></p><h2 id=\"what-else-can-we-do\" tabindex=\"-1\">What else can we do</h2><p>Although they can start very basic, there are some more significant things we can do with templates.</p><ul><li>Offer the option of Swift or Objective-C when creating a new file.</li><li>Change the filename based on what is entered, for example naming the file <code>UsersRepositoryTests</code> if <code>UsersRepository</code> is entered.</li><li>Ask for arguments to be entered in the new file window and then use these within the code.</li><li>Add file headers or copyright notices.</li><li>Add imports or skeleton code to be included in the file by default.</li></ul><p>Some example file templates can be found <a href=\"https://github.com/lordcodes/lordcodes-samples/tree/master/ios/create-xcode-file-templates\">on GitHub</a>, demonstrating some of the options available.</p><h2 id=\"it's-nice-to-share\" tabindex=\"-1\">It's nice to share</h2><p>As we explore the possibilities that file templates provide us, one problem becomes extremely clear. It would be really great if we could create project-specific templates and share them with the other developers on the project. Although templates for a specific project are not supported automatically by Xcode, it can be done through a clever use of symbolic links.</p><p>We should place all templates in a directory within our project, such as <code>FileTemplates</code>. It is likely the project is kept in source control, which will ensure the templates are tracked and shared with everyone else in the team.</p><p>The directory Xcode expects to find our templates should already exist if the steps were followed above. If not then we need to ensure it does.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">mkdir</span> <span class=\"token parameter variable\">-p</span> ~/Library/Developer/Xcode/Templates/File<span class=\"token punctuation\">\\</span> Templates</code></pre><p>Once the directory exists, the symbolic link can be created here that points to the templates within our Xcode project. It is worth mentioning that if we delete the project or move it, the symbolic link can simply be deleted and recreated.</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">ln</span> <span class=\"token parameter variable\">-s</span> <span class=\"token punctuation\">[</span>Project Location<span class=\"token punctuation\">]</span>/FileTemplates <span class=\"token punctuation\">\\</span>\n  ~/Library/Developer/Xcode/Templates/File<span class=\"token punctuation\">\\</span> Templates/<span class=\"token punctuation\">[</span>ProjectName<span class=\"token punctuation\">]</span></code></pre><p>For example:</p><pre class=\"language-shell\"><code class=\"language-shell\"><span class=\"token function\">ln</span> <span class=\"token parameter variable\">-s</span> ~/projects/github/chatapp/FileTemplates <span class=\"token punctuation\">\\</span>\n  ~/Library/Developer/Xcode/Templates/File<span class=\"token punctuation\">\\</span> Templates/ChatApp</code></pre><p>After restarting Xcode, any project templates will now be presented within the 'New File' window. It would obviously be great if Xcode could offer a solution without the extra work, however, for now it works nicely.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Xcode file templates can be a great way to get started quickly when creating new files. They are very powerful, although quite under-documented and there is much more they can do than discussed here.</p>",
			"date_published": "2018-12-14T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/map-dictionary-keys-to-different-type/",
			"url": "https://www.lordcodes.com/articles/map-dictionary-keys-to-different-type/",
			"title": "Map the keys of a dictionary to a different type",
			"content_html": "<p>The Swift standard library includes functions to transform the values of a <code>Dictionary</code>, we need to add one ourselves to do the same to the keys.</p><p>There are situations this can come in handy such as converting a <code>Dictionary</code> of analytics event parameters from using an internal enum for the keys to using Strings for reporting to our analytics API.</p><p>This neat little extension will allow us to do just that!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">Dictionary</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">mapKeys</span><span class=\"token operator\">&lt;</span><span class=\"token class-name\">NewKeyT</span><span class=\"token operator\">></span><span class=\"token punctuation\">(</span>\n        <span class=\"token omit keyword\">_</span> transform<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">(</span><span class=\"token class-name\">Key</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">NewKeyT</span>\n    <span class=\"token punctuation\">)</span> <span class=\"token keyword\">rethrows</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">NewKeyT</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">Value</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">var</span> newDictionary <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">NewKeyT</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">Value</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">try</span> forEach <span class=\"token punctuation\">{</span> key<span class=\"token punctuation\">,</span> value <span class=\"token keyword\">in</span>\n        <span class=\"token keyword\">let</span> newKey <span class=\"token operator\">=</span> <span class=\"token keyword\">try</span> <span class=\"token function\">transform</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span>\n            newDictionary<span class=\"token punctuation\">[</span>newKey<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> value\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">return</span> newDictionary\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-12-13T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/using-anchors-parent-constraints/",
			"url": "https://www.lordcodes.com/articles/using-anchors-parent-constraints/",
			"title": "Using anchors to match a parent view&#39;s constraints",
			"content_html": "<p>Swift extensions are really great, including when working with Auto Layout. We can make a child view fill its superview using constraints, as well as having insets between them. This is very useful when adding a child view controller to its parent within a subview.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">UIView</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">attachAnchors</span><span class=\"token punctuation\">(</span>to view<span class=\"token punctuation\">:</span> <span class=\"token class-name\">UIView</span><span class=\"token punctuation\">,</span> with insets<span class=\"token punctuation\">:</span> <span class=\"token class-name\">UIEdgeInsets</span> <span class=\"token operator\">=</span> <span class=\"token punctuation\">.</span>zero<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token class-name\">NSLayoutConstraint</span><span class=\"token punctuation\">.</span><span class=\"token function\">activate</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">[</span>\n            topAnchor<span class=\"token punctuation\">.</span><span class=\"token function\">constraint</span><span class=\"token punctuation\">(</span>\n                equalTo<span class=\"token punctuation\">:</span> view<span class=\"token punctuation\">.</span>topAnchor<span class=\"token punctuation\">,</span>\n                constant<span class=\"token punctuation\">:</span> insets<span class=\"token punctuation\">.</span>top\n            <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            rightAnchor<span class=\"token punctuation\">.</span><span class=\"token function\">constraint</span><span class=\"token punctuation\">(</span>\n                equalTo<span class=\"token punctuation\">:</span> view<span class=\"token punctuation\">.</span>rightAnchor<span class=\"token punctuation\">,</span>\n                constant<span class=\"token punctuation\">:</span> <span class=\"token operator\">-</span>insets<span class=\"token punctuation\">.</span><span class=\"token keyword\">right</span>\n            <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            bottomAnchor<span class=\"token punctuation\">.</span><span class=\"token function\">constraint</span><span class=\"token punctuation\">(</span>\n                equalTo<span class=\"token punctuation\">:</span> view<span class=\"token punctuation\">.</span>bottomAnchor<span class=\"token punctuation\">,</span>\n                constant<span class=\"token punctuation\">:</span> <span class=\"token operator\">-</span>insets<span class=\"token punctuation\">.</span>bottom\n            <span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            leftAnchor<span class=\"token punctuation\">.</span><span class=\"token function\">constraint</span><span class=\"token punctuation\">(</span>\n                equalTo<span class=\"token punctuation\">:</span> view<span class=\"token punctuation\">.</span>leftAnchor<span class=\"token punctuation\">,</span>\n                constant<span class=\"token punctuation\">:</span> insets<span class=\"token punctuation\">.</span><span class=\"token keyword\">left</span>\n            <span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-12-07T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/animating-view-colour-changes/",
			"url": "https://www.lordcodes.com/articles/animating-view-colour-changes/",
			"title": "Animating view colour changes",
			"content_html": "<p>When animating the addition of cells to a <code>UICollectionView</code>, we may notice that text and background colours aren't animating when using <code>UIView.animate</code>. Using <code>UIView.transition</code> instead works perfectly!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token class-name\">UIView</span><span class=\"token punctuation\">.</span><span class=\"token function\">transition</span><span class=\"token punctuation\">(</span>with<span class=\"token punctuation\">:</span> commentContainer<span class=\"token punctuation\">,</span> duration<span class=\"token punctuation\">:</span> <span class=\"token number\">0.6</span><span class=\"token punctuation\">,</span>\n                  options<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>transitionCrossDissolve<span class=\"token punctuation\">,</span> animations<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span>\n   commentContainer<span class=\"token punctuation\">.</span>backgroundColor <span class=\"token operator\">=</span> <span class=\"token class-name\">UIColor</span><span class=\"token punctuation\">(</span>red<span class=\"token punctuation\">:</span> <span class=\"token number\">17</span><span class=\"token punctuation\">,</span> green<span class=\"token punctuation\">:</span> <span class=\"token number\">215</span><span class=\"token punctuation\">,</span> blue<span class=\"token punctuation\">:</span> <span class=\"token number\">198</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token class-name\">UIView</span><span class=\"token punctuation\">.</span><span class=\"token function\">transition</span><span class=\"token punctuation\">(</span>with<span class=\"token punctuation\">:</span> commentLabel<span class=\"token punctuation\">,</span> duration<span class=\"token punctuation\">:</span> <span class=\"token number\">0.6</span><span class=\"token punctuation\">,</span>\n                  options<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>transitionCrossDissolve<span class=\"token punctuation\">,</span> animations<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span>\n   commentLabel<span class=\"token punctuation\">.</span>textColor <span class=\"token operator\">=</span> <span class=\"token class-name\">UIColor</span><span class=\"token punctuation\">(</span>red<span class=\"token punctuation\">:</span> <span class=\"token number\">143</span><span class=\"token punctuation\">,</span> green<span class=\"token punctuation\">:</span> <span class=\"token number\">155</span><span class=\"token punctuation\">,</span> blue<span class=\"token punctuation\">:</span> <span class=\"token number\">174</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">)</span></code></pre>",
			"date_published": "2018-12-06T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/time-intervals-explicit-units/",
			"url": "https://www.lordcodes.com/articles/time-intervals-explicit-units/",
			"title": "Create time intervals with explicit units",
			"content_html": "<p>In Swift, many APIs take a <code>TimeInterval</code> instead of just a <code>Double</code>, you need to know they are in seconds. Instead we can add functions that provide them with explicit units and allow us to convert them. It makes for a really readable call site!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">TimeInterval</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token comment\">// Hide the calculations from the call site</span>\n   <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">var</span> secondsPerHour<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Double</span> <span class=\"token punctuation\">{</span> <span class=\"token keyword\">return</span> <span class=\"token number\">60</span> <span class=\"token operator\">*</span> <span class=\"token number\">60</span> <span class=\"token punctuation\">}</span>\n   <span class=\"token keyword\">private</span> <span class=\"token keyword\">static</span> <span class=\"token keyword\">var</span> secondsPerMinute<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Double</span> <span class=\"token punctuation\">{</span> <span class=\"token keyword\">return</span> <span class=\"token number\">60</span> <span class=\"token punctuation\">}</span>\n\n   <span class=\"token comment\">// Functions to provide time intervals with explicit units</span>\n   <span class=\"token keyword\">static</span> <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">hours</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> value<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Double</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">TimeInterval</span> <span class=\"token punctuation\">{</span>\n      value <span class=\"token operator\">*</span> secondsPerHour\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">static</span> <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">minutes</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> value<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Double</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">TimeInterval</span> <span class=\"token punctuation\">{</span>\n      value <span class=\"token operator\">*</span> secondsPerMinute\n   <span class=\"token punctuation\">}</span>\n\n   <span class=\"token keyword\">static</span> <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">seconds</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> value<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Double</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">TimeInterval</span> <span class=\"token punctuation\">{</span>\n      value\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token comment\">// They make very readable call sites</span>\n<span class=\"token class-name\">TimeInterval</span><span class=\"token punctuation\">.</span><span class=\"token function\">hours</span><span class=\"token punctuation\">(</span><span class=\"token number\">3</span><span class=\"token punctuation\">)</span>\n<span class=\"token class-name\">TimeInterval</span><span class=\"token punctuation\">.</span><span class=\"token function\">minutes</span><span class=\"token punctuation\">(</span><span class=\"token number\">46</span><span class=\"token punctuation\">)</span>\n<span class=\"token class-name\">TimeInterval</span><span class=\"token punctuation\">.</span><span class=\"token function\">seconds</span><span class=\"token punctuation\">(</span><span class=\"token number\">35</span><span class=\"token punctuation\">)</span></code></pre>",
			"date_published": "2018-12-04T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/testing-on-android-using-junit-5/",
			"url": "https://www.lordcodes.com/articles/testing-on-android-using-junit-5/",
			"title": "Testing on Android using JUnit 5",
			"content_html": "<p>JUnit 4 has always been the standard unit testing framework for Android development, however, a production version of JUnit 5 has been available for <a href=\"https://github.com/junit-team/junit5/releases/tag/r5.0.0\">quite a while</a>. JUnit 5 is the next generation of JUnit testing and has quite a new structure. From a user-perspective it offers a number of useful new features and various other benefits. Often Android developers are used to waiting a while for new things from the Java-world to be an option on Android. In the case of JUnit 5, with some changes to your Gradle dependencies, you can use it right now from your Java and Kotlin unit tests.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/FalfGKh-ji-700.webp 700w\"><img src=\"https://www.lordcodes.com/img/FalfGKh-ji-700.jpeg\" alt=\"JUnit 5 logo\" title=\"Testing on Android with JUnit 5\" width=\"700\" height=\"375\"></picture></p><p>The architecture of JUnit 5 is quite a significant change from before, with the framework being split into three major components.</p><ul><li><strong>JUnit Platform</strong> is the underlying layer on which testing frameworks can run on the JVM and offers up the API for different test engines.</li><li><strong>JUnit Jupiter</strong> defines how we write JUnit 5 tests and then contains an engine for running these tests on the platform.</li><li><strong>JUnit Vintage</strong> gives us an engine for running our previous JUnit 4 tests. We don't need to worry about having to update all of our tests in one go, as we can use the vintage engine to run these and have both JUnit 4 and 5 tests within our project.</li></ul><p>As users of the testing framework, it's likely that the most interesting part is the new features we get access to. Nested tests allow us to put our tests into groups, increasing readability and allowing us to reduce repetition within test names. Parameterised tests are really powerful and can also reduce duplicating tests to give different inputs, the parameters can even be provided through a variety of mechanisms. Dynamic tests offer an API to generate tests on the fly using a test factory, rather than hard-coding each of the tests.</p><blockquote><p>Parameterised tests run tests with different inputs</p></blockquote><p>The JUnit 5 extension model allows us to extend the test framework and is the evolution of concepts from JUnit 4 such as <code>@Rule</code> and custom runners. The extension model will allow JUnit 5 to evolve with all developers and tool makers having the same public extension API. There are many more features beyond those listed here, all of which can be found in <a href=\"https://junit.org/junit5/docs/current/user-guide/#writing-tests\">the user guide</a>.</p><p>Now, let's get JUnit 5 running in our Android project.</p><h2 id=\"configuring-gradle\" tabindex=\"-1\">Configuring Gradle</h2><p>Thanks to <a href=\"https://github.com/mannodermaus\">Marcel Schnelle (mannodermaus)</a> there is an easy-to-use <a href=\"https://github.com/mannodermaus/android-junit5\">Gradle plugin</a> that will configure all the testing tasks to use JUnit 5. The plugin has a few <a href=\"https://github.com/mannodermaus/android-junit5/wiki/Getting-Started\">minimum requirements</a> that our project needs to meet, at the time of writing this is the Android Gradle plugin 3.2.0+, Gradle 4.7+ and Java 8+.</p><p>We will start by adding the plugin to our root <code>build.gradle</code> file using the latest version, which at time of writing is 1.3.2.0.</p><p><strong>→ /build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">buildscript <span class=\"token punctuation\">{</span>\n  dependencies <span class=\"token punctuation\">{</span>\n    classpath <span class=\"token interpolation-string\"><span class=\"token string\">\"de.mannodermaus.gradle.plugins:android-junit5:1.3.2.0\"</span></span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>After a successful Gradle sync, we will be ready to apply the plugin to any Android modules we wish to use JUnit 5 in.</p><p><strong>→ /app/build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">apply plugin<span class=\"token punctuation\">:</span> <span class=\"token string\">'de.mannodermaus.android-junit5'</span>\n\ndependencies <span class=\"token punctuation\">{</span>\n  testImplementation <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.jupiter:junit-jupiter-api:5.3.2\"</span></span>\n  testRuntimeOnly <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.jupiter:junit-jupiter-engine:5.3.2\"</span></span>\n  testImplementation <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.jupiter:junit-jupiter-params:5.3.2\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p>If there are JUnit 4 tests in the project we are configuring, then we will also need to keep the JUnit 4 dependency and enable the JUnit vintage test engine mentioned above.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">testImplementation <span class=\"token interpolation-string\"><span class=\"token string\">\"junit:junit:4.12\"</span></span>\ntestRuntimeOnly <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.vintage:junit-vintage-engine:5.3.2\"</span></span></code></pre><p>Once the plugin and the Gradle dependencies have been configured, we can run tests in the same way as we were previously using the same Gradle tasks and run configurations in Android Studio.</p><p>If we need them, there are <a href=\"https://github.com/mannodermaus/android-junit5/wiki/Configuration\">some options</a> for configuring the test environment within Gradle. Our settings go in a <code>junitPlatform</code> block within the existing <code>testOptions</code>, where we may already be doing some configuration. The most common use-case would be for filtering which tests are executed. We could use the filters to divide our tests into unit and integration and then have them run for different variants, as an example.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">android <span class=\"token punctuation\">{</span>\n  testOptions <span class=\"token punctuation\">{</span>\n    junitPlatform <span class=\"token punctuation\">{</span>\n      filters <span class=\"token punctuation\">{</span>\n        includePattern <span class=\"token interpolation-string\"><span class=\"token string\">\"^(tests_to_include_regex)$\"</span></span>\n        excludePattern <span class=\"token interpolation-string\"><span class=\"token string\">\"^(tests_to_exclude_regex)$\"</span></span>\n\n        includeTags <span class=\"token interpolation-string\"><span class=\"token string\">\"slow\"</span></span>\n        excludeTags <span class=\"token interpolation-string\"><span class=\"token string\">\"integration\"</span></span>\n      <span class=\"token punctuation\">}</span>\n      debugFilters <span class=\"token punctuation\">{</span>\n        includeTags <span class=\"token interpolation-string\"><span class=\"token string\">\"integration\"</span></span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>For any more information on the plugin, all the setup and usage instructions can be found <a href=\"https://github.com/mannodermaus/android-junit5\">on GitHub</a>.</p><h3 id=\"jvm-tests-only\" tabindex=\"-1\">JVM tests only</h3><p>If our unit tests are only going to be ran on the JVM, no Robolectric or Android required, then we can get away without the Gradle plugin. To do this we can remove the plugin classpath entry from the root <code>build.gradle</code> and the line where the plugin is applied within the app module <code>build.gradle</code>. Instead we need to add some configuration to <code>testOptions</code> to enable running with JUnit 5.</p><p><strong>→ /app/build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">android <span class=\"token punctuation\">{</span>\n  testOptions <span class=\"token punctuation\">{</span>\n    unitTests<span class=\"token punctuation\">.</span>all <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">useJUnitPlatform</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>We lose the per-variant filters that were demonstrated above if we go down this route. However, for most Android projects that aren't using Robolectric this should definitely be sufficient.</p><h2 id=\"writing-the-tests\" tabindex=\"-1\">Writing the tests</h2><p>Let's write some tests to explore the new features of JUnit 5 and how we should go about using it in our apps. We will be using <a href=\"http://joel-costigliola.github.io/assertj/\">AssertJ</a> for our assertions, mainly for readability within the samples. We will be testing a very simple repository that allows us to look up contacts using their IDs, starting with the JUnit 4 version.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>assertj<span class=\"token punctuation\">.</span>core<span class=\"token punctuation\">.</span>api<span class=\"token punctuation\">.</span>Assertions<span class=\"token punctuation\">.</span>assertThat\n<span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>junit<span class=\"token punctuation\">.</span>Test\n\n<span class=\"token keyword\">class</span> ContactsRepositoryTest <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> repository <span class=\"token operator\">=</span> <span class=\"token function\">ContactsRepository</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n  <span class=\"token annotation builtin\">@Test</span>\n  <span class=\"token keyword\">fun</span> <span class=\"token function\">findContact_givenExistingId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> id <span class=\"token operator\">=</span> <span class=\"token number\">2</span>\n    <span class=\"token keyword\">val</span> expectedContact <span class=\"token operator\">=</span> <span class=\"token function\">Contact</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">,</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Melanie\"</span></span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">val</span> actualContact <span class=\"token operator\">=</span> repository<span class=\"token punctuation\">.</span><span class=\"token function\">findContact</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>actualContact<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">isEqualTo</span><span class=\"token punctuation\">(</span>expectedContact<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>Converting this test to JUnit 5 is as simple as changing the import for <code>@Test</code>. Projects with many more tests, using more features of JUnit 4, may have more changes that are required. As mentioned above, we can start new tests in JUnit 5 and then either leave the JUnit 4 ones as is, or convert them gradually.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token comment\">// Before</span>\n<span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>junit<span class=\"token punctuation\">.</span>Test\n\n<span class=\"token comment\">// After</span>\n<span class=\"token keyword\">import</span> org<span class=\"token punctuation\">.</span>junit<span class=\"token punctuation\">.</span>jupiter<span class=\"token punctuation\">.</span>api<span class=\"token punctuation\">.</span>Test</code></pre><h2 id=\"descriptive-test-names\" tabindex=\"-1\">Descriptive test names</h2><p>A common structure for tests is breaking them into <strong>given</strong>, <strong>when</strong> and <strong>then</strong>.</p><ul><li>The <strong>given</strong> clause involves setting up the conditions for the test, such as mocking or configuring the component we are about to test.</li><li>Within the <strong>when</strong> clause, we execute the behaviour we are looking to verify.</li><li>It is in the <strong>then</strong> clause that we check the behaviour is working correctly with any assertions.</li></ul><p>This structure is fairly clear within the body of the test function, however, in the naming of the function some issues may start to arise.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Test</span>\n<span class=\"token keyword\">fun</span> <span class=\"token function\">givenContactsLoadedAndIdMatches_whenFindContact_thenContactReturned</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token annotation builtin\">@Test</span>\n<span class=\"token keyword\">fun</span> <span class=\"token function\">givenContactsNotLoadedAndIdMatches_whenFindContact_thenNoContactReturned</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><p>Some approaches could be taken to reduce the length, such as using shorter wording in the given clauses and potentially removing the then clause from the name. This does result in losing some detail, which can be really useful in test names to quickly see in the test report what is going on and to demonstrate what a test is supposed to do. It is also much easier to read a descriptive sentence than the camel-case seen in function names.</p><p>JUnit 5 introduces the <code>@DisplayName</code> annotation, which can be used to provide a descriptive name for the test report. The same result can be achieved in Kotlin through the use of back-ticks around the function name. The advantage of the <code>@DisplayName</code> approach is that we keep the searchable and familiar function name, whereas the back-tick approach avoids the need to maintain both the function name and annotation.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Test</span>\n<span class=\"token annotation builtin\">@DisplayName</span><span class=\"token punctuation\">(</span>\n  <span class=\"token string-literal singleline\"><span class=\"token string\">\"Given contacts are loaded but the ID is invalid, When we find a contact, Then no contact is returned.\"</span></span>\n<span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">fun</span> <span class=\"token function\">findContact_givenExistingId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n<span class=\"token annotation builtin\">@Test</span>\n<span class=\"token keyword\">fun</span> <span class=\"token function\">`Given contacts are loaded but ID invalid, When we find a contact, Then no contact returned`</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre><h2 id=\"structuring-tests\" tabindex=\"-1\">Structuring tests</h2><p>A common reason for test names growing in length is having multiple tests with the same starting condition. Beyond naming, a similar starting condition can cause test bodies to grow in length as well! To solve the issue, JUnit 5 introduces <code>@Nested</code>, allowing you to group a set of tests into an inner class. The group can have a shared starting state and can also have a display name specified, reducing the length of individual test function names. The nested structure is shown within the test report, making it very readable.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token annotation builtin\">@Nested</span>\n<span class=\"token annotation builtin\">@DisplayName</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"Given valid contact ID\"</span></span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">inner</span> <span class=\"token keyword\">class</span> ValidContactId  <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">private</span> <span class=\"token keyword\">val</span> id <span class=\"token operator\">=</span> <span class=\"token number\">2</span>\n\n  <span class=\"token annotation builtin\">@Test</span>\n  <span class=\"token annotation builtin\">@DisplayName</span><span class=\"token punctuation\">(</span><span class=\"token string-literal singleline\"><span class=\"token string\">\"When find contact, then correct contact returned\"</span></span><span class=\"token punctuation\">)</span>\n  <span class=\"token keyword\">fun</span> <span class=\"token function\">findContact_givenExistingId</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">val</span> expectedContact <span class=\"token operator\">=</span> <span class=\"token function\">Contact</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">,</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"Melanie\"</span></span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">val</span> actualContact <span class=\"token operator\">=</span> repository<span class=\"token punctuation\">.</span><span class=\"token function\">findContact</span><span class=\"token punctuation\">(</span>id<span class=\"token punctuation\">)</span>\n\n    <span class=\"token function\">assertThat</span><span class=\"token punctuation\">(</span>actualContact<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">.</span><span class=\"token function\">isEqualTo</span><span class=\"token punctuation\">(</span>expectedContact<span class=\"token punctuation\">)</span>\n  <span class=\"token punctuation\">}</span>\n\n  <span class=\"token operator\">..</span><span class=\"token punctuation\">.</span>\n<span class=\"token punctuation\">}</span></code></pre><p>After fleshing out the tests for this repository more, with a few tests in each group, we can peek at the test report to see how it all looks. 👀</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/wpj62nUvka-1024.webp 1024w\"><img src=\"https://www.lordcodes.com/img/wpj62nUvka-1024.jpeg\" alt=\"Android Studio test report\" title=\"Android Studio test report\" width=\"1024\" height=\"449\"></picture></p><p>The code we have written is available <a href=\"https://github.com/lordcodes/lordcodes-samples/tree/master/android/unit-testing-on-android-using-junit-5\">on GitHub</a>.</p><h2 id=\"instrumentation-tests\" tabindex=\"-1\">Instrumentation tests</h2><p>We have been discussing unit tests only and as we all know instrumentation tests, usually using <a href=\"https://developer.android.com/training/testing/espresso/\">Espresso</a>, are also very important. Currently, our Espresso tests will be using JUnit 4, which can be left as it was previously. This means using the JUnit 4 test runner, as opposed to adding the JUnit 5 vintage engine and using the new infrastructure.</p><blockquote><p>Instrumentation tests using the JUnit 5 Gradle plugin are still considered experimental</p></blockquote><p>The Gradle plugin we used to introduce JUnit 5 on Android has support for instrumentation tests, which at the time of writing is considered experimental. From checking the GitHub issues page for the plugin, many people have had problems using JUnit 5 for their instrumentation test suite. When the situation changes this article will be updated with the current details of using it.</p><p>Since JUnit 5 is built upon Java 8, to use it we need a <code>minSdkVersion</code> of 26 or above. Before we start freaking out, this can be achieved by running the tests with a product flavour that has the minimum SDK increased to this level.</p><p>To write and run our instrumentation tests using the JUnit 5 framework, we will need some Gradle configuration. A little bit more is required than for unit tests, due to needing to tell the system to to use the plugin's runner builder and ensuring tests running on the device work correctly.</p><p><strong>→ /app/build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">android <span class=\"token punctuation\">{</span>\n  defaultConfig <span class=\"token punctuation\">{</span>\n    testInstrumentationRunner <span class=\"token interpolation-string\"><span class=\"token string\">\"android.support.test.runner.AndroidJUnitRunner\"</span></span>\n    testInstrumentationRunnerArgument <span class=\"token interpolation-string\"><span class=\"token string\">\"runnerBuilder\"</span></span><span class=\"token punctuation\">,</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"de.mannodermaus.junit5.AndroidJUnit5Builder\"</span></span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\ndependencies <span class=\"token punctuation\">{</span>\n  androidTestImplementation <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.jupiter:junit-jupiter-api:5.3.2\"</span></span>\n  androidTestImplementation <span class=\"token interpolation-string\"><span class=\"token string\">\"de.mannodermaus.junit5:android-instrumentation-test:0.2.2\"</span></span>\n\n  androidTestRuntimeOnly <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.jupiter:junit-jupiter-engine:5.3.2\"</span></span>\n  androidTestRuntimeOnly <span class=\"token interpolation-string\"><span class=\"token string\">\"org.junit.platform:junit-platform-runner:1.3.2\"</span></span>\n  androidTestRuntimeOnly <span class=\"token interpolation-string\"><span class=\"token string\">\"de.mannodermaus.junit5:android-instrumentation-test-runner:0.2.2\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p>It is noteworthy that instrumentation tests tend to have less need for JUnit 5, due to there being less tests and fewer variants of similar tests, in general. This will of course depend heavily from project to project though! To find out more, please check out the plugin's <a href=\"https://github.com/mannodermaus/android-junit5#instrumentation-test-support\">GitHub page</a>.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>We have only considered a few small aspects of writing JUnit 5 tests, as there is simply so much to look at. To find out more, there is a detailed <a href=\"https://junit.org/junit5/docs/current/user-guide/#writing-tests\">user guide</a> covering all parts of the framework and how to go about writing tests and customising the test process.</p><p>By using JUnit 5 in our Android app testing we are using the latest evolution of the JUnit framework. It gives us access to more features, helps us make tests as readable as possible, reduce duplication within our tests and extending the test framework has never been easier. Hopefully it will catch on more in the Android community and become the &quot;standard&quot; for Android development sooner rather than later.</p>",
			"date_published": "2018-11-30T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/a-modular-analytics-layer-in-swift/",
			"url": "https://www.lordcodes.com/articles/a-modular-analytics-layer-in-swift/",
			"title": "A modular analytics layer in Swift",
			"content_html": "<p>There is a saying, &quot;<em>if a tree falls in a forest and no one is around to hear it, does it make a sound?</em>&quot; Monitoring user behaviour is a bit like that; if people are using your app in a particular way, but you don't know about it, then how can you work out how to improve it.</p><p>There are many different options available to us in order to monitor user behaviour, such as user testing, collecting surveys and analytics. Here we are going to be discussing the topic of analytics, specifically using it within a Swift app.</p><p>When building and improving your apps, knowing how it is being used by real users <em>in the wild</em> can be very valuable. It allows you to make data-informed decisions rather than just estimating what you think is a good idea. You can also use it to verify and test out ideas once they have been released to your users.</p><p>Whilst adding analytics to an app can be quick and easy, ensuring the implementation is easy to use, alter and extend can be more complex. The implementation should be able to stand the test of time and give us the flexibility to make changes to the analytics data we are reporting in the future. We are going to look through one way of building an analytics layer in Swift, that is both modular and extensible.</p><h2 id=\"backend\" tabindex=\"-1\">Backend</h2><p>When analytics data is captured within our apps, we would normally want to submit this to our preferred backend. This allows data to be collected over time and analysis to be ran over the data.</p><p>It is very common for this backend to be a third-party SDK such as: <a href=\"https://firebase.google.com/docs/analytics/get-started?platform=ios\">Firebase Analytics</a> or <a href=\"https://docs.mixpanel.com/docs/tracking-methods/sdks/swift\">MixPanel</a>. You may also want to use a tool such as <a href=\"https://segment.com/docs/connections/sources/catalog/libraries/mobile/ios/\">Segment</a>, to control where the data is sent and have the flexibility to change the destination whenever you want.</p><p>Your backend may be an in-house analytics system, reporting data to your own backend API or pumping data into a data warehouse of some kind. This can be beneficial if your data is specialised or you need to do something with it that the third-party destinations don't support.</p><p>Whichever backend solution has been settled on, it is good to wrap its API in one of your own, to avoid the codebase being littered with a specific analytics API. Doing this will give you the flexibility to change the solution more easily and help make your code more maintainable.</p><h2 id=\"features\" tabindex=\"-1\">Features</h2><p>We are going to build a layer that avoids using a static API, puts any backend APIs behind a protocol, uses the power of Swift enums and pairs each event with the pieces of data it needs to contain.</p><p>More specifically it should:</p><ol><li>Be easy to report new and existing events.</li><li>Allow the data be sent to whichever analytics backend we wish to use, even multiple.</li><li>Be testable and mockable, allowing it to be an injected dependency.</li><li>Allow events to be reported from anywhere in the app, but encourage best practices.</li><li>Have compile-time safety of events and their properties.</li></ol><p>There are a few different components that make up our analytics layer, each covering part of the process.</p><h2 id=\"the-main-event\" tabindex=\"-1\">The main event</h2><p>The events themselves can be modelled through our <code>AnalyticsEvent</code> enum.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">enum</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">Equatable</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> addContactTapped\n    <span class=\"token keyword\">case</span> <span class=\"token function\">contactSelected</span><span class=\"token punctuation\">(</span>index<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Int</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">case</span> <span class=\"token function\">messageSent</span><span class=\"token punctuation\">(</span>threadType<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ThreadType</span><span class=\"token punctuation\">,</span> length<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Int</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">case</span> userSignedIn\n<span class=\"token punctuation\">}</span></code></pre><p>The enum contains a case for each event we want to fire, with associated values for any pieces of data that need to be attached to the event. When we report an event, we are required to provide any data it needs. By writing events in this way we can reduce the amount of code required to report an event, whilst checking for correctness at compile time.</p><p>When the event is passed further it provides the set of parameters that are attached to it. These parameters use an enum for their names, to allow them to be mapped differently later on, similar to the events themselves.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">AnalyticsEvent</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> parameters<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">Parameter</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">switch</span> <span class=\"token keyword\">self</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>addContactTapped<span class=\"token punctuation\">,</span>\n           <span class=\"token punctuation\">.</span>userSignedIn<span class=\"token punctuation\">:</span>\n          <span class=\"token keyword\">return</span> <span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token punctuation\">]</span>\n      <span class=\"token keyword\">case</span> <span class=\"token keyword\">let</span> <span class=\"token punctuation\">.</span><span class=\"token keyword\">case</span> <span class=\"token function\">contactSelected</span><span class=\"token punctuation\">(</span>index<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n          <span class=\"token keyword\">return</span> <span class=\"token punctuation\">[</span>\n              <span class=\"token punctuation\">.</span>contactIndex<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">(</span>describing<span class=\"token punctuation\">:</span> index<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">]</span>\n      <span class=\"token keyword\">case</span> <span class=\"token keyword\">let</span> <span class=\"token punctuation\">.</span><span class=\"token function\">messageSent</span><span class=\"token punctuation\">(</span>threadType<span class=\"token punctuation\">,</span> length<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n          <span class=\"token keyword\">return</span> <span class=\"token punctuation\">[</span>\n              <span class=\"token punctuation\">.</span>threadType<span class=\"token punctuation\">:</span> threadType<span class=\"token punctuation\">.</span>rawValue<span class=\"token punctuation\">,</span>\n              <span class=\"token punctuation\">.</span>messageLength<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">(</span>describing<span class=\"token punctuation\">:</span> length<span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">]</span>\n      <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">enum</span> <span class=\"token class-name\">Parameter</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">Equatable</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">case</span> contactIndex\n        <span class=\"token keyword\">case</span> messageLength\n        <span class=\"token keyword\">case</span> threadType\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>For writing the switch statement over the <code>AnalyticsEvent</code> enum it is best to avoid using a default case, as this enforces that each new event is handled.</p><h2 id=\"providers\" tabindex=\"-1\">Providers</h2><p>Each backend you wish to report data to will conform to our <code>AnalyticsProvider</code> protocol. This will document the different analytics operations we can perform.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">protocol</span> <span class=\"token class-name\">AnalyticsProvider</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The <code>report(event:)</code> function is taking our event enum as an argument. This allows each provider to map the event to whichever format they need it in. For example, Firebase Analytics requires events to contain underscores (_) instead of hyphens (-). Once the event has been mapped, it would then be reported to the destination for that particular provider, often calling through to the provider's SDK.</p><p>A final solution may also report screens, user properties, preferences and more. These would be added to the <code>AnalyticsProvider</code> protocol.</p><h2 id=\"let's-implement-a-provider\" tabindex=\"-1\">Let's implement a provider</h2><p>Making our backend conform to the provider protocol is relatively simple, let's start by building one for Firebase Analytics. The event name and parameters are mapped to strings, before being passed through to the Firebase Analytics SDK <code>logEvent</code> function.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">FirebaseAnalyticsProvider</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsProvider</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">let</span> eventMapper <span class=\"token operator\">=</span> <span class=\"token class-name\">AnalyticsEventMapper</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">let</span> name <span class=\"token operator\">=</span> eventMapper<span class=\"token punctuation\">.</span><span class=\"token function\">eventName</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span><span class=\"token punctuation\">:</span> event<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">let</span> parameters <span class=\"token operator\">=</span> eventMapper<span class=\"token punctuation\">.</span><span class=\"token function\">parameters</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span><span class=\"token punctuation\">:</span> event<span class=\"token punctuation\">)</span>\n        <span class=\"token class-name\">Analytics</span><span class=\"token punctuation\">.</span><span class=\"token function\">logEvent</span><span class=\"token punctuation\">(</span>name<span class=\"token punctuation\">,</span> parameters<span class=\"token punctuation\">:</span> parameters<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The flexibility of the solution means we can easily build another provider to log events to the console.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">LoggingAnalyticsProvider</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsProvider</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">let</span> eventMapper <span class=\"token operator\">=</span> <span class=\"token class-name\">AnalyticsEventMapper</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">let</span> name <span class=\"token operator\">=</span> eventMapper<span class=\"token punctuation\">.</span><span class=\"token function\">eventName</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span><span class=\"token punctuation\">:</span> event<span class=\"token punctuation\">)</span>\n        <span class=\"token function\">print</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Event reported: </span><span class=\"token interpolation-punctuation punctuation\">\\(</span><span class=\"token interpolation\">name</span><span class=\"token interpolation-punctuation punctuation\">)</span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>We can create a provider for whichever destination we wish to use.</p><h2 id=\"get-mapping\" tabindex=\"-1\">Get mapping</h2><p>Each provider needs to convert the event enum into a reporting format. Most analytics SDKs require events in a string format and so it an be a good idea to provide a default mapper that does this.</p><p>If a particular app doesn't need the flexibility for each provider to control the mapping, we can instead return data in the correct format directly within the <code>AnalyticsEvent</code>.</p><p>For now we will give ourselves full flexibility, by using a separate mapper.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">AnalyticsEventMapper</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">eventName</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span> event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">String</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token operator\">...</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">parameters</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span> event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token operator\">...</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The first part to the mapping process is to get a name for the event. This is as simple as using a switch statement to map each event case to a <code>String</code>.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">func</span> <span class=\"token function-definition function\">eventName</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span> event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">String</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">switch</span> event <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>addContactTapped<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"addContact_tapped\"</span></span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>contactSelected<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"contact_selected\"</span></span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>messageSent<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"message_sent\"</span></span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>userSignedIn<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"user_signedIn\"</span></span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The second part is getting a dictionary of event parameters.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">func</span> <span class=\"token function-definition function\">parameters</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span> event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">]</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> newParameters <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">String</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    event<span class=\"token punctuation\">.</span>parameters<span class=\"token punctuation\">.</span>forEach <span class=\"token punctuation\">{</span> key<span class=\"token punctuation\">,</span> value <span class=\"token keyword\">in</span>\n        <span class=\"token keyword\">let</span> newKey <span class=\"token operator\">=</span> <span class=\"token function\">parameterName</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span><span class=\"token punctuation\">:</span> key<span class=\"token punctuation\">)</span>\n        newParameters<span class=\"token punctuation\">[</span>newKey<span class=\"token punctuation\">]</span> <span class=\"token operator\">=</span> value\n    <span class=\"token punctuation\">}</span>\n    <span class=\"token keyword\">return</span> newParameters\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">func</span> <span class=\"token function-definition function\">parameterName</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">for</span> parameter<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">.</span><span class=\"token class-name\">Parameter</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">String</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">switch</span> parameter <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>contactIndex<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"contact_index\"</span></span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>messageLength<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"message_length\"</span></span>\n    <span class=\"token keyword\">case</span> <span class=\"token punctuation\">.</span>threadType<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string-literal\"><span class=\"token string\">\"thread_type\"</span></span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The <code>parameters(for:)</code> function is simply converting the dictionary keys from an enum to a <code>String</code>. If used in multiple places, it can be easily extracted to a generic extension on <code>Dictionary</code>.</p><h2 id=\"putting-it-all-together\" tabindex=\"-1\">Putting it all together</h2><p>We now need to bring together all of the components we have built and create the API for our analytics layer, the <code>AnalyticsReporter</code>. The reporter is the dependency you will be injecting and using throughout your app to report events.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">AnalyticsReporter</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">let</span> providers<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">AnalyticsProvider</span><span class=\"token punctuation\">]</span>\n\n    <span class=\"token keyword\">init</span><span class=\"token punctuation\">(</span>providers<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">AnalyticsProvider</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span>providers <span class=\"token operator\">=</span> providers\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        providers<span class=\"token punctuation\">.</span>forEach <span class=\"token punctuation\">{</span>\n            <span class=\"token short-argument\">$0</span><span class=\"token punctuation\">.</span><span class=\"token function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> event<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>This reporter allows multiple analytics providers to be used, obviously if an app only required a single provider we could decide whether this was worth supporting or not. Due to each analytics backend being wrapped with our provider, the reporter is pretty simple.</p><p>As with the provider, a final solution may also include reporting of other entities such as screens and user properties.</p><h2 id=\"time-to-use-it\" tabindex=\"-1\">Time to use it</h2><p>We can now put our implementation into practice to see how it is to use.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">ContactsViewModel</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">let</span> coordinator<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ContactsCoordinator</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">let</span> analyticsReporter<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsReporter</span>\n\n    <span class=\"token keyword\">init</span><span class=\"token punctuation\">(</span>coordinator<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ContactsCoordinator</span><span class=\"token punctuation\">,</span> analyticsReporter<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsReporter</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span>coordinator <span class=\"token operator\">=</span> coordinator\n        <span class=\"token keyword\">self</span><span class=\"token punctuation\">.</span>analyticsReporter <span class=\"token operator\">=</span> analyticsReporter\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">contactSelected</span><span class=\"token punctuation\">(</span>at index<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Int</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        analyticsReporter<span class=\"token punctuation\">.</span><span class=\"token function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span><span class=\"token function\">contactSelected</span><span class=\"token punctuation\">(</span>index<span class=\"token punctuation\">:</span> index<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        coordinator<span class=\"token punctuation\">.</span><span class=\"token function\">startContactThreads</span><span class=\"token punctuation\">(</span>at<span class=\"token punctuation\">:</span> index<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">addContactTapped</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        analyticsReporter<span class=\"token punctuation\">.</span><span class=\"token function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>addContactTapped<span class=\"token punctuation\">)</span>\n        coordinator<span class=\"token punctuation\">.</span><span class=\"token function\">startContactCreation</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>The <code>AnalyticsReporter</code> can be injected wherever we wish to use it, in the case above in a <code>ContactsViewModel</code>. Using the API is as simple as selecting the correct event and providing any values it requires.</p><p>If we need to report a new event, we just need to add it to the <code>AnalyticsEvent</code> enum, provide its parameters and update any mapping code. ⚒</p><h2 id=\"testing\" tabindex=\"-1\">Testing</h2><p>It is very important that our analytics code be testable and that it doesn't make any other code more difficult to test. To verify the correct events have been reported, we can create a <code>TestingAnalyticsProvider</code> within our unit test sources. The test provider stores reported events so that they can be asserted on afterwards.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">TestingAnalyticsProvider</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsProvider</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> eventsReported <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">report</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AnalyticsEvent</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        eventsReported<span class=\"token punctuation\">.</span><span class=\"token function\">append</span><span class=\"token punctuation\">(</span>event<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>That wraps up implementing, using and testing our new analytics layer. In general the approach we have put forward is flexible and can be altered where necessary to suit a particular app's needs.</p><p>We have seen that:</p><ul><li>Our implementation uses a modular approach that should minimise the impact analytics has on the rest of the app.</li><li>It is easy to configure and report both new and existing events.</li><li>Each destination is wrapped in a provider protocol, giving the flexibility to support any backend we wish to use, including a test one.</li><li>By avoiding a static API, we encourage the reporter dependency to be instantiated or provided via dependency injection, whilst it still being easy to do so.</li><li>The use of an enum for the event type enforces compile-time safety for events and the properties they each require.</li></ul>",
			"date_published": "2018-11-27T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/enable-java-8-compatibility-for-kotlin-sources/",
			"url": "https://www.lordcodes.com/articles/enable-java-8-compatibility-for-kotlin-sources/",
			"title": "Enable Java 8 compatibility for Kotlin sources",
			"content_html": "<p>Enabling Java 8 compatibility via the <code>compileOptions</code> block only works for Java sources. To do the same for Kotlin you need to use <code>kotlinOptions</code> on any KotlinCompile Gradle tasks. Interesting…</p><p><strong>For Kotlin</strong></p><pre class=\"language-kotlin\"><code class=\"language-kotlin\">tasks<span class=\"token punctuation\">.</span><span class=\"token function\">withType</span><span class=\"token punctuation\">(</span>org<span class=\"token punctuation\">.</span>jetbrains<span class=\"token punctuation\">.</span>kotlin<span class=\"token punctuation\">.</span>gradle<span class=\"token punctuation\">.</span>tasks<span class=\"token punctuation\">.</span>KotlinCompile<span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">all</span> <span class=\"token punctuation\">{</span>\n    kotlinOptions <span class=\"token punctuation\">{</span>\n        jvmTarget <span class=\"token operator\">=</span> JavaVersion<span class=\"token punctuation\">.</span>VERSION_1_8\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p><strong>For Java</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">android <span class=\"token punctuation\">{</span>\n  compileOptions <span class=\"token punctuation\">{</span>\n    sourceCompatibility JavaVersion<span class=\"token punctuation\">.</span>VERSION_1_8\n    targetCompatibility JavaVersion<span class=\"token punctuation\">.</span>VERSION_1_8\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-11-27T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/gradle-dependencies-using-kotlin-in-buildsrc/",
			"url": "https://www.lordcodes.com/articles/gradle-dependencies-using-kotlin-in-buildsrc/",
			"title": "Manage Gradle dependencies using Kotlin code in buildSrc",
			"content_html": "<p>Using Kotlin to maintain our Gradle dependencies within the buildSrc directory can be really great.</p><ol><li>Allows us to use a familiar syntax</li><li>Provides auto-complete within Groovy or Kotlin Gradle scripts</li><li>Can click through to a particular dependencies definition</li></ol><p>Sweet!</p><p><strong>→ /buildSrc/src/main/java/com/myapp/Versions.kt</strong></p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">package</span> com<span class=\"token punctuation\">.</span>myapp\n\n<span class=\"token keyword\">object</span> Versions <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">object</span> AndroidX <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> appCompat <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"1.0.2\"</span></span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> kotlin <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"1.3.10\"</span></span>\n  <span class=\"token operator\">..</span><span class=\"token punctuation\">.</span>\n<span class=\"token punctuation\">}</span></code></pre><p><strong>→ /buildSrc/src/main/java/com/myapp/Libs.kt</strong></p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">package</span> com<span class=\"token punctuation\">.</span>myapp\n\n<span class=\"token keyword\">object</span> Libs <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">object</span> AndroidX <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> appCompat <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"androidx.appcompat:appcompat:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>AndroidX<span class=\"token punctuation\">.</span>appCompat</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> kotlinStdlib <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"org.jetbrains.kotlin:kotlin-stdlib:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>kotlin</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p><strong>→ /src/app/build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\"><span class=\"token keyword\">import</span> com<span class=\"token punctuation\">.</span>myapp<span class=\"token punctuation\">.</span>Libs\n\ndependencies <span class=\"token punctuation\">{</span>\n  implementation Libs<span class=\"token punctuation\">.</span>kotlinStdlib\n  implementation Libs<span class=\"token punctuation\">.</span>AndroidX<span class=\"token punctuation\">.</span>appCompat\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-11-27T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/protocol-functions-default-parameters/",
			"url": "https://www.lordcodes.com/articles/protocol-functions-default-parameters/",
			"title": "Protocol functions with default parameter values",
			"content_html": "<p>Being able to specify default parameter values in Swift allows us to reduce the number of function overloads in our code. For protocols it is still possible as long as we use an extension and delegate to the version without the default values.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">protocol</span> <span class=\"token class-name\">ErrorController</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">showError</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> error<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> delegate<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ErrorViewControllerDelegate</span><span class=\"token operator\">?</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">extension</span>  <span class=\"token class-name\">ErrorController</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">showError</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> error<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> delegate<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ErrorViewControllerDelegate</span><span class=\"token operator\">?</span> <span class=\"token operator\">=</span> <span class=\"token nil constant\">nil</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">showError</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">,</span> delegate<span class=\"token punctuation\">:</span> delegate<span class=\"token punctuation\">)</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">ContactsViewController</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">UIViewController</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">ErrorController</span> <span class=\"token punctuation\">{</span>\n   <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">showError</span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> error<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span><span class=\"token punctuation\">,</span> delegate<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ErrorViewControllerDelegate</span><span class=\"token operator\">?</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token function\">print</span><span class=\"token punctuation\">(</span>error<span class=\"token punctuation\">)</span>\n   <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">let</span> contacts<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ErrorController</span> <span class=\"token operator\">=</span> <span class=\"token class-name\">ContactsViewController</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\ncontacts<span class=\"token punctuation\">.</span><span class=\"token function\">showError</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"I don't need a delegate.\"</span></span><span class=\"token punctuation\">)</span></code></pre>",
			"date_published": "2018-11-26T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/access-call-site-swift-literals/",
			"url": "https://www.lordcodes.com/articles/access-call-site-swift-literals/",
			"title": "Access the call site of a function using special Swift literals",
			"content_html": "<p>Accessing information about the call site of a function is surprisingly simple in Swift by simply using <code>#file</code>, <code>#function</code> and <code>#line</code>. This can be a great help when we want to put assertions within a shared function or print text without losing the original context.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span>  <span class=\"token class-name\">XCTestCase</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">struct</span> <span class=\"token class-name\">UnexpectedNilError</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">Error</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">unwrapAssert</span><span class=\"token operator\">&lt;</span><span class=\"token class-name\">ValueT</span><span class=\"token operator\">></span><span class=\"token punctuation\">(</span><span class=\"token omit keyword\">_</span> value<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ValueT</span><span class=\"token operator\">?</span><span class=\"token punctuation\">,</span>\n                              message<span class=\"token punctuation\">:</span> <span class=\"token class-name\">String</span> <span class=\"token operator\">=</span> <span class=\"token string-literal\"><span class=\"token string\">\"Unexpected nil\"</span></span><span class=\"token punctuation\">,</span>\n                              file<span class=\"token punctuation\">:</span> <span class=\"token class-name\">StaticString</span> <span class=\"token operator\">=</span> <span class=\"token literal constant\">#file</span><span class=\"token punctuation\">,</span>\n                              line<span class=\"token punctuation\">:</span> <span class=\"token class-name\">UInt</span> <span class=\"token operator\">=</span> <span class=\"token literal constant\">#line</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">throws</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">ValueT</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">guard</span> <span class=\"token keyword\">let</span> value <span class=\"token operator\">=</span> value <span class=\"token keyword\">else</span> <span class=\"token punctuation\">{</span>\n            <span class=\"token class-name\">XCTFail</span><span class=\"token punctuation\">(</span>message<span class=\"token punctuation\">,</span> file<span class=\"token punctuation\">:</span> file<span class=\"token punctuation\">,</span> line<span class=\"token punctuation\">:</span> line<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">throw</span>  <span class=\"token class-name\">UnexpectedNilError</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">return</span> value\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-11-26T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/safely-index-items-within-a-collection/",
			"url": "https://www.lordcodes.com/articles/safely-index-items-within-a-collection/",
			"title": "Safely index items within a collection",
			"content_html": "<p>We can make some great things with extensions in Swift, as well as subscript functions. This one allows us to safely access collection elements by index, getting back an optional instead of errors being thrown!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">Collection</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">subscript</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">safe</span> index<span class=\"token punctuation\">:</span> <span class=\"token class-name\">Index</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">Element</span><span class=\"token operator\">?</span> <span class=\"token punctuation\">{</span>\n        indices<span class=\"token punctuation\">.</span><span class=\"token function\">contains</span><span class=\"token punctuation\">(</span>index<span class=\"token punctuation\">)</span> <span class=\"token operator\">?</span> <span class=\"token keyword\">self</span><span class=\"token punctuation\">[</span>index<span class=\"token punctuation\">]</span> <span class=\"token punctuation\">:</span> <span class=\"token nil constant\">nil</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">let</span> numbers <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token number\">1</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span><span class=\"token punctuation\">,</span> <span class=\"token number\">3</span><span class=\"token punctuation\">,</span> <span class=\"token number\">4</span><span class=\"token punctuation\">]</span>\nnumbers<span class=\"token punctuation\">[</span><span class=\"token keyword\">safe</span><span class=\"token punctuation\">:</span> <span class=\"token number\">3</span><span class=\"token punctuation\">]</span> <span class=\"token comment\">// 4</span>\nnumbers<span class=\"token punctuation\">[</span><span class=\"token keyword\">safe</span><span class=\"token punctuation\">:</span> <span class=\"token number\">10</span><span class=\"token punctuation\">]</span> <span class=\"token comment\">// nil, no error</span></code></pre>",
			"date_published": "2018-11-25T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/gradle-dependencies-using-kotlin/",
			"url": "https://www.lordcodes.com/articles/gradle-dependencies-using-kotlin/",
			"title": "Manage your Gradle dependencies in Kotlin, even from Groovy scripts",
			"content_html": "<p>When defining the dependencies for a Gradle project, such as an Android app, there are situations that call for duplicated information. A common case is that libraries or plugins can often come with multiple dependencies, which are usually released together with matching versions. Maintaining these dependencies requires the version to be duplicated and then kept up-to-date as new versions are released.</p><p>Another case is that it is common to have a multi-module project, where we may want a dependency to be added to multiple modules. Similarly to the case with versions, the dependency definition would be duplicated for each module and then kept in-sync moving forward.</p><p>It is clear that in both cases we may want to define the dependencies in one place and then access this location from wherever the dependency definition is needed.</p><h2 id=\"the-groovy-way\" tabindex=\"-1\">The Groovy way</h2><p>There is a mechanism for sharing your dependency configuration using Groovy, by adding some extra properties in our root <code>build.gradle</code> file, similar to below.</p><p><strong>→ /build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">buildscript <span class=\"token punctuation\">{</span>\n  ext<span class=\"token punctuation\">.</span>versions <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">'kotlin'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'1.3.10'</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">'dagger'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'2.19'</span>\n  <span class=\"token punctuation\">]</span>\n\n  ext<span class=\"token punctuation\">.</span>deps <span class=\"token punctuation\">[</span>\n    <span class=\"token string\">'kotlin'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n      <span class=\"token string\">'stdlib'</span><span class=\"token punctuation\">:</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"org.jetbrains.kotlin:kotlin-stdlib:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">versions<span class=\"token punctuation\">.</span>kotlin</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">,</span>\n      <span class=\"token string\">'test'</span><span class=\"token punctuation\">:</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"org.jetbrains.kotlin:kotlin-test-common:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">versions<span class=\"token punctuation\">.</span>kotlin</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n    <span class=\"token punctuation\">]</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">'dagger'</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">[</span>\n      <span class=\"token string\">'runtime'</span><span class=\"token punctuation\">:</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.google.dagger:dagger:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">,</span>\n      <span class=\"token string\">'compiler'</span><span class=\"token punctuation\">:</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.google.dagger:dagger-compiler:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">,</span>\n      <span class=\"token string\">'androidRuntime'</span><span class=\"token punctuation\">:</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.google.dagger:dagger-android:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">,</span>\n      <span class=\"token string\">'androidCompiler'</span><span class=\"token punctuation\">:</span> <span class=\"token interpolation-string\"><span class=\"token string\">\"com.google.dagger:dagger-android-processor:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token punctuation\">]</span>\n  <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre><p><strong>→ /app/build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">dependencies <span class=\"token punctuation\">{</span>\n  implementation deps<span class=\"token punctuation\">.</span>kotlin<span class=\"token punctuation\">.</span>stdlib\n\n  implementation deps<span class=\"token punctuation\">.</span>dagger<span class=\"token punctuation\">.</span>runtime\n  implementation deps<span class=\"token punctuation\">.</span>dagger<span class=\"token punctuation\">.</span>androidRuntime\n  kapt deps<span class=\"token punctuation\">.</span>dagger<span class=\"token punctuation\">.</span>compiler\n  kapt deps<span class=\"token punctuation\">.</span>dagger<span class=\"token punctuation\">.</span>androidCompiler\n\n  testImplementation deps<span class=\"token punctuation\">.</span>kotlin<span class=\"token punctuation\">.</span>test\n<span class=\"token punctuation\">}</span></code></pre><p>Sharing the configuration via the root <code>build.gradle</code> achieves the goal of having a single location to maintain. Only needing to update dependency versions in a single file is a great time-saver as well. Unfortunately from practice, when using the Groovy Gradle DSL auto-complete is often missing or incomplete in this situation, making it awkward to use.</p><p>On top of this, <a href=\"https://gradle.org/whats-new/gradle-5/\">Gradle 5.0</a> is now available which includes the production-ready Kotlin Gradle DSL. When we convert the above solution to Kotlin it isn't as nice to use in Kotlin as it is in Groovy. The map syntax can be achieved using <code>mapOf</code>, but reading the data to pass to <code>implementation</code> requires some casting to fit with the statically typed language.</p><h2 id=\"kotlin-to-the-rescue\" tabindex=\"-1\">Kotlin to the rescue</h2><p>As many developers have found with their main app source code, Kotlin can help with defining our dependency configurations as well, from both Groovy and Kotlin Gradle scripts.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/yxUelyoALR-1400.webp 1400w\"><img src=\"https://www.lordcodes.com/img/yxUelyoALR-1400.jpeg\" alt=\"Kotlin and Gradle logos\" title=\"Kotlin and Gradle - a match made in heaven?\" width=\"1400\" height=\"613\"></picture></p><p>When ran, Gradle will check for a <code>buildSrc</code> directory in the root of the project, placing any code that is found into the classpath of our build. This is really handy and allows us to put Kotlin code into <code>buildSrc</code> and then reference it from our Gradle scripts. To get started we just need a little bit of structure.</p><p><strong>→ /buildSrc/build.gradle.kts</strong></p><pre><code>plugins {\n  `kotlin-dsl`\n}\n</code></pre><p>The Kotlin DSL plugin needs to be specified for <code>buildSrc</code>.</p><p><strong>→ /buildSrc/src/main/kotlin/Versions.kt</strong></p><p>Our source files need to be placed within the standard sources directory structure. To use inner objects, for now we need to include the sources within a package, e.g. 'com.ourapp'.</p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">object</span> Versions <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> dagger <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"2.21\"</span></span>\n  <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> ktlint <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"0.29.0\"</span></span>\n  <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> kotlin <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"1.3.11\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p><strong>→ /buildSrc/src/main/kotlin/Dependencies.kt</strong></p><pre class=\"language-kotlin\"><code class=\"language-kotlin\"><span class=\"token keyword\">object</span> Plugins <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> kotlin <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"org.jetbrains.kotlin:kotlin-gradle-plugin:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>kotlin</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> ktlint <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"com.github.shyiko:ktlint:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>ktlint</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">object</span> Libs <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> kotlinStdlib <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"org.jetbrains.kotlin:kotlin-stdlib:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>kotlin</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> daggerRuntime <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"com.google.dagger:dagger:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> daggerCompiler <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"com.google.dagger:dagger-compiler:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> daggerAndroidRuntime <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"com.google.dagger:dagger-android:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n    <span class=\"token keyword\">const</span> <span class=\"token keyword\">val</span> daggerAndroidCompiler <span class=\"token operator\">=</span> <span class=\"token string-literal singleline\"><span class=\"token string\">\"com.google.dagger:dagger-android-processor:</span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${</span><span class=\"token expression\">Versions<span class=\"token punctuation\">.</span>dagger</span><span class=\"token interpolation-punctuation punctuation\">}</span></span><span class=\"token string\">\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p>Once Gradle has been synced, we can now reference our dependencies within our Gradle scripts. This is pretty much the same as we used with the Groovy extra properties solution above.</p><p><strong>→ /app/build.gradle</strong></p><pre class=\"language-groovy\"><code class=\"language-groovy\">dependencies <span class=\"token punctuation\">{</span>\n  implementation Libs<span class=\"token punctuation\">.</span>kotlinStdlib\n\n  implementation Libs<span class=\"token punctuation\">.</span>daggerRuntime\n  implementation Libs<span class=\"token punctuation\">.</span>daggerAndroidRuntime\n  kapt Libs<span class=\"token punctuation\">.</span>daggerCompiler\n  kapt Libs<span class=\"token punctuation\">.</span>daggerAndroidCompiler\n\n  ktlint Plugins<span class=\"token punctuation\">.</span>ktlint\n<span class=\"token punctuation\">}</span></code></pre><p>Using <code>buildSrc</code> and Kotlin sources achieves the goal of having a single location to maintain and we can even reduce it to a single Kotlin source file if it makes sense to. The solution can be used in the same way from both Groovy and Kotlin Gradle DSL without being altered, which frees us up to change our Gradle scripts to Kotlin if we want to.</p><p>The best thing about defining dependencies in this way is that we get access to effective auto-complete and being able to click through to where a dependency is defined from our Gradle scripts, super useful.</p><p>A good tool to look into is <a href=\"https://github.com/ben-manes/gradle-versions-plugin\">Ben Manes' Gradle Versions Plugin</a>, which will inform us of any dependencies with new versions. Once we have the latest versions, we can simply update them in <code>Versions.kt</code>.</p><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>Naturally, for the reasons given I prefer to use the <code>buildSrc</code> and Kotlin source approach in my Android projects. It is really nice to use with both Groovy Gradle scripts and those written using the Gradle Kotlin DSL.</p>",
			"date_published": "2018-11-23T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/managing-secrets-within-an-ios-app/",
			"url": "https://www.lordcodes.com/articles/managing-secrets-within-an-ios-app/",
			"title": "Managing secrets within an iOS app",
			"content_html": "<p>Almost all iOS apps need private values, such as API keys, secrets and passwords. Some of these may need to be used in the source code, to setup third-party SDKs or backend APIs. Some secrets may be needed during the build process or to use developer tools, such as communicating with an Apple Developer account.</p><p>Simple approaches for including secrets into an app would include: putting values directly into the code, placing them into build scripts or keeping them in the <code>Info.plist</code> file. Unfortunately, these approaches mean the secrets are committed to source control and are visible to anyone with access to the the code. Furthermore, scripts and plist files added to the app bundle can be extracted from the compiled app.</p><p>We are going to look through some more secure ways of managing secrets within our iOS projects, in order to access them from code. It is worth noting that it is practically impossible to keep anything within an app 100% secret, as apps are &quot;out in the wild&quot; on users' devices. A good approach is to enforce a suitable level of protection for the situation, for example a banking app should probably have a higher level of security than a to-do list app.</p><h2 id=\"control-the-sources\" tabindex=\"-1\">Control the sources</h2><p>It is important to keep secrets out of source control for both open and closed source projects for various reasons.</p><ol><li>By committing secrets to source control, you are sharing these values with all users who have read-access to the repository, including anyone who gets access in the future. You may have users who need to access the project, but not necessarily use all of the secrets.</li><li>After a user checks out the repository, they would gain a copy of all the secrets stored on their local machine.</li><li>If your source control system is compromised, not only would the source code be obtained, so would all of the passwords and other secrets.</li></ol><p>Git allows us to include a <code>.gitignore</code> file, where we can list files (or expressions) that should be kept out. If these files are required by our app, each developer just creates these files and adds any required values. We could include template versions of these files in Git or a guide for what is needed in documentation, including contact details for who to provide secrets if they are required.</p><h2 id=\"cocoapods-keys\" tabindex=\"-1\">Cocoapods Keys</h2><p>As most iOS developers are aware, many iOS projects use <a href=\"https://github.com/CocoaPods/CocoaPods\">Cocoapods</a> as a dependency manager. Cocoapods includes a plugin system that allows its processes to be hooked into. One such plugin that can be used to manage your app secrets securely is <a href=\"https://github.com/orta/cocoapods-keys\">cocoapods-keys</a>.</p><p>Not only does cocoapods-keys keep the secrets out of the project sources, it holds them securely in your system keychain. When pods are installed or updated, the developer is asked for each key that has no value already stored. An Objective-C class is generated that contains obfuscated versions of keys and their values. As this class is built by running Cocoapods, the <code>Pods/CocoaPodsKeys</code> directory can be added to the <code>.gitignore</code>.</p><p>The plugin has many advantages:</p><ul><li>It asks for a value to be provided for each key, avoiding the need to document the required secrets. This makes it very easy for each developer to get their project environment configured.</li><li>The source file is generated, which allows it to be easily kept out of source control.</li><li>Secrets are scrambled within the generated sources, to protect against the keys being extracted from the app binary.</li><li>It can be used from both Swift and Objective-C sources.</li><li>By reading from the keychain, we could access the secrets within build scripts if we needed to.</li><li>We can share keys between different projects that use cocoapods-keys.</li></ul><h2 id=\"let's-setup-our-keys\" tabindex=\"-1\">Let's setup our keys</h2><p>Incorporating cocoapods-keys into our project is very simple and starts with including the plugin into our <code>Podfile</code>.</p><pre class=\"language-ruby\"><code class=\"language-ruby\">plugin <span class=\"token string-literal\"><span class=\"token string\">'cocoapods-keys'</span></span><span class=\"token punctuation\">,</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token symbol\">:project</span> <span class=\"token operator\">=></span> <span class=\"token string-literal\"><span class=\"token string\">\"ChatApp\"</span></span><span class=\"token punctuation\">,</span>\n  <span class=\"token symbol\">:target</span> <span class=\"token operator\">=></span> <span class=\"token string-literal\"><span class=\"token string\">\"ChatApp\"</span></span><span class=\"token punctuation\">,</span>\n  <span class=\"token symbol\">:keys</span> <span class=\"token operator\">=></span> <span class=\"token punctuation\">[</span>\n    <span class=\"token string-literal\"><span class=\"token string\">\"ChatAPIClientSecretProd\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token string-literal\"><span class=\"token string\">\"ChatAPIClientSecretTest\"</span></span><span class=\"token punctuation\">,</span>\n    <span class=\"token string-literal\"><span class=\"token string\">\"AnalyticsWriteKey\"</span></span>\n  <span class=\"token punctuation\">]</span>\n<span class=\"token punctuation\">}</span></code></pre><p>After we next run <code>pod install</code>, we will be asked to enter the value for each of our keys listed above. Once all keys are configured, the plugin will generate a source file that can be referenced in our code to read the keys.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">import</span> <span class=\"token class-name\">Keys</span>\n\n<span class=\"token keyword\">let</span> keys <span class=\"token operator\">=</span> <span class=\"token class-name\">ChatAppKeys</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n<span class=\"token class-name\">Analytics</span><span class=\"token punctuation\">.</span><span class=\"token function\">setup</span><span class=\"token punctuation\">(</span>with<span class=\"token punctuation\">:</span> keys<span class=\"token punctuation\">.</span>analyticsWriteKey<span class=\"token punctuation\">)</span></code></pre><p>For values like our backend API secret, where we may want it to be different for debug and release, we can include both keys and then read a different one at runtime. There are obviously many different ways of handling this, depending on the exact use case we have. Therefore, we aren't going to discuss all possible options here and will simply look at switching based on whether the app is built in the debug configuration.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">var</span> apiClientSecret <span class=\"token punctuation\">{</span>\n    <span class=\"token directive property\"><span class=\"token directive-name\">#if</span> DEBUG</span>\n    <span class=\"token keyword\">return</span> keys<span class=\"token punctuation\">.</span>chatApiClientSecretTest\n    <span class=\"token directive property\"><span class=\"token directive-name\">#else</span></span>\n    <span class=\"token keyword\">return</span> keys<span class=\"token punctuation\">.</span>chatApiClientSecretProd\n    <span class=\"token directive property\"><span class=\"token directive-name\">#endif</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p>If you are using Cocoapods in your project, I would recommend looking into <a href=\"https://github.com/orta/cocoapods-keys\">cocoapods-keys</a> over other options, due to it being a secure and easy-to-use way to solve the problem.</p><h2 id=\"doing-things-ourselves\" tabindex=\"-1\">Doing things ourselves</h2><p>Many projects don't use Cocoapods or we may not want to use a plugin and so we can also consider implementing a solution ourselves. Secrets will be passed into the build process, where they will be made available as environment variables. We can then read these variables and use them to generate a source file that will give our code access to our secret values.</p><blockquote><p>We can have different values for different environments</p></blockquote><p>Xcode offers <em>xcconfig</em> files that can be linked to a particular build configuration in order to load in settings specified within them. An xcconfig file can be specified for each build configuration, allowing us to have different values for each environment. We may wish to point our app at our production API for release apps, but a test backend for debug apps.</p><p>Note that if a particular app doesn't need different values depending on the build configuration, we can use a shell script instead of the xcconfig files and source the file into our final build phase later on.</p><p>We start off by creating example versions of our xcconfig files. If we place these files within a directory such as <code>BuildConfig</code> it will keep them separate from other project files. It is recommended to include these files into the project, so that they appear within Xcode, but we should ensure they aren't added to any targets within the <em>Target Membership</em> area of the <em>File Inspector</em>.</p><p><strong>→ debug.example.xccconfig</strong></p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token constant\">CHAT_API_CLIENT_SECRET</span> <span class=\"token operator\">=</span> <span class=\"token constant\">CHAT_API_CLIENT_SECRET_TEST</span>\n<span class=\"token constant\">ANALYTICS_WRITE_KEY</span> <span class=\"token operator\">=</span> <span class=\"token constant\">ANALYTICS_WRITE_KEY</span></code></pre><p><strong>→ release.example.xccconfig</strong></p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token constant\">CHAT_API_CLIENT_SECRET</span> <span class=\"token operator\">=</span> <span class=\"token constant\">CHAT_API_CLIENT_SECRET_PROD</span>\n<span class=\"token constant\">ANALYTICS_WRITE_KEY</span> <span class=\"token operator\">=</span> <span class=\"token constant\">ANALYTICS_WRITE_KEY</span></code></pre><p>By duplicating and renaming the example files we can easily create the <em>real</em> files that will be used by the project. As with the example files, we want these files in the project, but not attached to any targets.</p><p><strong>→ debug.xccconfig</strong></p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token constant\">CHAT_API_CLIENT_SECRET</span> <span class=\"token operator\">=</span> <span class=\"token number\">123456789</span>\n<span class=\"token constant\">ANALYTICS_WRITE_KEY</span> <span class=\"token operator\">=</span> abcdefgh</code></pre><p><strong>→ release.xccconfig</strong></p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token constant\">CHAT_API_CLIENT_SECRET</span> <span class=\"token operator\">=</span> <span class=\"token number\">987654321</span>\n<span class=\"token constant\">ANALYTICS_WRITE_KEY</span> <span class=\"token operator\">=</span> abcdefgh</code></pre><p>To avoid the real xcconfig files being added to source control, they should be listed in the <em>.gitignore</em> file. We can use a regular expression in the rule to catch the files for all configurations.</p><pre><code>BuildConfig/*.example.xcconfig\n</code></pre><p>The final step, is telling Xcode to use our xcconfig files, which is specified within the project file under <code>Info → Configurations</code>. Make sure to select an xcconfig for each build configuration and for the target you need.</p><h2 id=\"generating-the-source\" tabindex=\"-1\">Generating the source</h2><p>When Xcode builds your project, the values in the xcconfig files are made available as environment variables. You could simply use these values in your <code>Info.plist</code> file if you wished with the form <code>$(CHAT_API_CLIENT_SECRET)</code>. We have already discussed that putting secrets into plist files isn't very secure, but have mentioned it for completeness.</p><p>We are going to generate a source file using a tool called <a href=\"https://github.com/krzysztofzablocki/Sourcery\">Sourcery</a> and then reference this source file in our code to access our secrets. Needless to say, we will need to start by adding <a href=\"https://github.com/krzysztofzablocki/Sourcery\">Sourcery</a> to our project, for example including a standalone version within our repository or using Cocoapods.</p><p>Sourcery uses a template system, where we create a stencil file to show the tool how to generate our code. We will create <code>AppSecrets.stencil</code> including some syntax to substitute in the secret values when the file is generated from the template.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">struct</span> <span class=\"token class-name\">AppSecrets</span> <span class=\"token punctuation\">{</span>\n  <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> chatApiClientSecret<span class=\"token operator\">=</span><span class=\"token string-literal\"><span class=\"token string\">\"{{ argument.chatApiClientSecret }}\"</span></span>\n  <span class=\"token keyword\">static</span> <span class=\"token keyword\">let</span> analyticsWriteKey<span class=\"token operator\">=</span><span class=\"token string-literal\"><span class=\"token string\">\"{{ argument.analyticsWriteKey }}\"</span></span>\n<span class=\"token punctuation\">}</span></code></pre><p>We next need to add a build phase to our project by selecting the project file, then selecting the correct target and going to the Build Phases tab.</p><pre class=\"language-bash\"><code class=\"language-bash\">Tools/Sourcery/bin/sourcery\n    <span class=\"token parameter variable\">--sources</span> Sources\n    <span class=\"token parameter variable\">--templates</span> Templates/AppSecrets.stencil\n    <span class=\"token parameter variable\">--output</span> Generated\n    <span class=\"token parameter variable\">--args</span> <span class=\"token assign-left variable\">chatApiClientSecret</span><span class=\"token operator\">=</span><span class=\"token punctuation\">\\</span>\"<span class=\"token variable\">$CHAT_API_CLIENT_SECRET</span><span class=\"token punctuation\">\\</span>\",\n           <span class=\"token assign-left variable\">analyticsWriteKey</span><span class=\"token operator\">=</span><span class=\"token punctuation\">\\</span>\"<span class=\"token variable\">$ANALYTICS_WRITE_KEY</span><span class=\"token punctuation\">\\</span>\"</code></pre><ul><li>The path to the Sourcery executable will depend on how it is installed.</li><li>The sources argument needs to be specified, even though it isn't used in this situation. We can simply point it to our main sources, or any valid directory.</li><li>The templates argument is a path from the root of the project to our template file.</li><li>The output directory is where the generated source file is written. We need to ensure this folder exists, possibly by adding <code>mkdir -p Generated</code> at the start of the build phase.</li><li>Within args, values are separated by commas in the form: <code>arg1=one,arg2=two</code>. It is a good idea to escape as above incase the secret values contain any special characters.</li></ul><p>We can use <a href=\"https://gist.github.com/lordcodes/f9bd45773f1872516bb3e2aaee45cd3f\">a more complex script</a> instead of manually specifying secrets within the build phase. This can be beneficial if there are more than a couple of secrets or the build phase is hard to maintain.</p><p>After adding the build phase, we can build the app as normal and then add the generated <code>AppSecrets.swift</code> file to the project so that it is compiled and linked to the project target. As with the xcconfig files, we should add <code>AppSecrets.swift</code> to our <em>.gitignore</em> file to keep it out of Git.</p><p>Using secrets within our code is as simple as referencing our generated struct.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token class-name\">Analytics</span><span class=\"token punctuation\">.</span><span class=\"token function\">setup</span><span class=\"token punctuation\">(</span>with<span class=\"token punctuation\">:</span> <span class=\"token class-name\">AppSecrets</span><span class=\"token punctuation\">.</span>analyticsWriteKey<span class=\"token punctuation\">)</span></code></pre><h2 id=\"wrap-up\" tabindex=\"-1\">Wrap up</h2><p>The goal we wanted to achieve was being able to reference secret values within our source code, without these values themselves needing to be kept in source control. The two solutions we have looked at are quite different, but both achieve the same goal.</p><p>By using cocoapods-keys, we can avoid the manual setup and also avoid the values being stored in plain-text anywhere in the project. However, our solution using Sourcery can be used without Cocoapods and will still require very little maintenance. There will definitely be even more solutions available online for more use cases, it will come down to using the most appropriate solution for the situation.</p>",
			"date_published": "2018-11-20T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/sharing-accessibility-ids-app-and-tests/",
			"url": "https://www.lordcodes.com/articles/sharing-accessibility-ids-app-and-tests/",
			"title": "Sharing accessibility identifiers between app and tests",
			"content_html": "<p>For identifying views within UI tests we can use accessibility identifiers, which are <code>String</code> values. We can register all of our identifiers within an enum, using an extension to set them on our views. By adding the enum to the app target and the UI test target, an extension can be added to find views within tests suing our ID enum. It's really nice to use an enum, avoiding duplicating the strings and avoiding errors!</p><p><strong>App sources</strong></p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">UIAccessibilityIdentification</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">var</span> viewAccessibilityIdentifier<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ViewAccessibilityIdentifier</span><span class=\"token operator\">?</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">get</span> <span class=\"token punctuation\">{</span> <span class=\"token function\">fatalError</span><span class=\"token punctuation\">(</span><span class=\"token string-literal\"><span class=\"token string\">\"Not implemented\"</span></span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">}</span>\n        <span class=\"token keyword\">set</span> <span class=\"token punctuation\">{</span>\n            accessibilityIdentifier <span class=\"token operator\">=</span> newValue<span class=\"token operator\">?</span><span class=\"token punctuation\">.</span>rawValue\n        <span class=\"token punctuation\">}</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\naddContactButton<span class=\"token punctuation\">.</span>viewAccessibilityIdentifier <span class=\"token operator\">=</span> <span class=\"token punctuation\">.</span>addContactButton</code></pre><p><strong>Test sources</strong></p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">extension</span> <span class=\"token class-name\">XCUIElementQuery</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">subscript</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">:</span> <span class=\"token class-name\">ViewAccessibilityIdentifier</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">XCUIElement</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">self</span><span class=\"token punctuation\">[</span>key<span class=\"token punctuation\">.</span>rawValue<span class=\"token punctuation\">]</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token class-name\">XCUIApplication</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>buttons<span class=\"token punctuation\">[</span><span class=\"token punctuation\">.</span>addContactButton<span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">tap</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre>",
			"date_published": "2018-11-16T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/protocol-function-return-self-type/",
			"url": "https://www.lordcodes.com/articles/protocol-function-return-self-type/",
			"title": "Protocol function that returns the Self type",
			"content_html": "<p>We may find situations in which we want a protocol function to return the current type, here the metatype <code>Self</code> can come in handy. In these situations rather than just returning the protocol type, we likely want to return the type that conforms to the protocol. An associated type can be added to the protocol that defaults to <code>Self</code> to achieve this. Pretty handy!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">protocol</span> <span class=\"token class-name\">ChatThreadsRobot</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">associatedtype</span> <span class=\"token class-name\">ChatThreadsType</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">ChatThreadsRobot</span> <span class=\"token operator\">=</span> <span class=\"token keyword\">Self</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">tapCreateThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">ChatThreadsType</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">extension</span> <span class=\"token class-name\">ConnectionThreadsRobot</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">ChatThreadsRobot</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">tapCreateThread</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token class-name\">ConnectionThreadsRobot</span> <span class=\"token punctuation\">{</span>\n        app<span class=\"token punctuation\">.</span>buttons<span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"createThreadButton\"</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">tap</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">self</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-11-12T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/metatype-self-to-return-current-type/",
			"url": "https://www.lordcodes.com/articles/metatype-self-to-return-current-type/",
			"title": "Using metatype Self to return current type",
			"content_html": "<p>A helpful keyword in Swift is <code>Self</code>, which is a metatype that represents the current type. The current type may be the class, subclass or current implementer of a protocol, depending on where it is used.</p><p>A handy use-case for it is to avoid specifying generic placeholder types. Neat!</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">ThreadRobot</span><span class=\"token operator\">&lt;</span><span class=\"token class-name\">CallerT</span><span class=\"token punctuation\">:</span> <span class=\"token class-name\">CallerRobot</span><span class=\"token operator\">></span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> <span class=\"token keyword\">let</span> app <span class=\"token operator\">=</span> <span class=\"token class-name\">XCUIApplication</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">func</span> <span class=\"token function-definition function\">tapCompleteButton</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token operator\">-></span> <span class=\"token keyword\">Self</span> <span class=\"token punctuation\">{</span>\n        app<span class=\"token punctuation\">.</span>otherElements<span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"actionButtonRail\"</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span>buttons<span class=\"token punctuation\">[</span><span class=\"token string-literal\"><span class=\"token string\">\"Complete\"</span></span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">tap</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> <span class=\"token keyword\">self</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre>",
			"date_published": "2018-11-09T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/child-view-controller-subview-constraints/",
			"url": "https://www.lordcodes.com/articles/child-view-controller-subview-constraints/",
			"title": "Constraints for a child view controller within a subview",
			"content_html": "<p>When a <code>UIViewController</code> is added within one of it's parent's subviews, there can be an issue where it doesn't expand to fill it. This can often happen when we only tested on a specific device size.</p><p>The fix involves preventing the auto-resizing mask from being turned into constraints and ensuring the child view controller's anchor constraints are all attached to the edge's of its container view.</p><pre class=\"language-swift\"><code class=\"language-swift\"><span class=\"token function\">addChild</span><span class=\"token punctuation\">(</span>child<span class=\"token punctuation\">)</span>\ncontainerView<span class=\"token punctuation\">.</span><span class=\"token function\">addSubview</span><span class=\"token punctuation\">(</span>child<span class=\"token punctuation\">.</span>view<span class=\"token punctuation\">)</span>\nchild<span class=\"token punctuation\">.</span>view<span class=\"token punctuation\">.</span>translatesAutoresizingMaskIntoConstraints <span class=\"token operator\">=</span> <span class=\"token boolean\">false</span>\nchild<span class=\"token punctuation\">.</span>view<span class=\"token punctuation\">.</span><span class=\"token function\">attachAnchors</span><span class=\"token punctuation\">(</span>to<span class=\"token punctuation\">:</span> containerView<span class=\"token punctuation\">)</span>\nchild<span class=\"token punctuation\">.</span><span class=\"token function\">didMove</span><span class=\"token punctuation\">(</span>toParent<span class=\"token punctuation\">:</span> <span class=\"token keyword\">self</span><span class=\"token punctuation\">)</span></code></pre>",
			"date_published": "2018-10-23T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/welcome-to-android-studio-3-0/",
			"url": "https://www.lordcodes.com/articles/welcome-to-android-studio-3-0/",
			"title": "Welcome to Android Studio 3.0",
			"content_html": "<p>After a long wait, Android Studio 3.0 has finally been released to the stable channel. This means everyone should be updating their IDE to the latest and greatest version. There are so many new features and improvements it is just a no brainer! I will go over the new features later on, but for now I will discuss the process of updating and cover the breaking changes in the new Gradle plugin.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/UpsHHDZZCH-1200.webp 1200w\"><img src=\"https://www.lordcodes.com/img/UpsHHDZZCH-1200.jpeg\" alt=\"Android Studio 3.0 with logo\" title=\"Android Studio 3.0 - It's arrived!\" width=\"1200\" height=\"600\"></picture></p><h3 id=\"how-to-update\" tabindex=\"-1\">How to update</h3><h4 id=\"updating-the-ide-and-plugin\" tabindex=\"-1\">Updating the IDE and plugin</h4><p>Android Studio should have prompted you to update to 3.0, if not then go to <em>Check for updates</em> in the menu to do so.</p><p>Once you launch your project in 3.0 for the first time, you will be told there is a new version of the plugin to update to. You can continue to use your project as it is, but you will miss out on many of the new features and improvements until you update. Simply, follow the prompts to have your project updated to version 3 of the Gradle plugin and to use the latest version of Gradle 4.</p><p>If for some reason you need to do this manually:</p><ol><li>Open <code>gradle-wrapper.properties</code></li><li>Enter the latest version of Gradle (above 4.1)</li><li>Open <code>build.gradle</code> in the root of the project</li><li>Ensure it contains the Google Maven repository and version 3 of the plugin. <em>Note: there might be a version higher than 3.0.0 available, so use the latest one.</em></li></ol><h4 id=\"dependency-configurations\" tabindex=\"-1\">Dependency configurations</h4><p>Previously, when defining dependencies you would use <em>compile.</em></p><pre class=\"language-groovy\"><code class=\"language-groovy\">compile <span class=\"token string\">'com.android.support:support-compat:27.0.0'</span></code></pre><p>This has now been deprecated in favour of <code>implementation</code> and <code>api</code>. In general, you can simply update all dependencies to use <code>implementation</code>. However, if your project is a library and it leaks one its module’s interfaces you may need to use <code>api</code> for that instead.</p><p>To understand the difference, please read this <a href=\"https://jeroenmols.com/blog/2017/06/14/androidstudio3/\">detailed guide</a>.</p><h4 id=\"flavour-dimensions\" tabindex=\"-1\">Flavour dimensions</h4><p>Variants are now automatically matched, which means an app’s debug variant will automatically use a library module debug variant. The same happens for product flavours as well, such as <em>demo</em> and <em>trial</em>.</p><p>To ensure this mechanism works correctly, it is now required that all product flavours are assigned to a particular flavour dimension. If you don’t need to use different dimensions, you can simply create one and assign all the flavours to it.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">flavorDimensions <span class=\"token interpolation-string\"><span class=\"token string\">\"default\"</span></span>\n\nproductFlavors <span class=\"token punctuation\">{</span>\n  prod <span class=\"token punctuation\">{</span>\n    dimension <span class=\"token interpolation-string\"><span class=\"token string\">\"default\"</span></span>\n    <span class=\"token punctuation\">...</span>\n  <span class=\"token punctuation\">}</span>\n\n  dev <span class=\"token punctuation\">{</span>\n    dimension <span class=\"token interpolation-string\"><span class=\"token string\">\"default\"</span></span>\n    <span class=\"token punctuation\">...</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><p>If you use a build type or flavour that doesn’t exist in one of your library modules, a fallback will need to be specified. This isn’t required for <code>debug</code> or <code>release</code> as they are present in all modules automatically. The plugin will select the first fallback from the list which is found.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">debug <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">...</span> <span class=\"token punctuation\">}</span>\nrelease <span class=\"token punctuation\">{</span> <span class=\"token punctuation\">...</span> <span class=\"token punctuation\">}</span>\nstaging <span class=\"token punctuation\">{</span>\n  matchingFallbacks <span class=\"token operator\">=</span> <span class=\"token punctuation\">[</span><span class=\"token string\">'debug'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">'release'</span><span class=\"token punctuation\">]</span>\n  <span class=\"token punctuation\">...</span>\n<span class=\"token punctuation\">}</span></code></pre><h4 id=\"3rd-party-plugins-you-no-longer-need\" tabindex=\"-1\">3rd party plugins you no longer need</h4><p>If you are still using the <code>android-apt</code> plugin for annotation processing support, you should remove that and use the built-in <code>annotationProcessor</code>. The third party plugin is no longer supported.</p><p>Similarly, many people have been using <code>retrolambda</code> for Java 8 features support. This is no longer required and will simply be provided automatically, so you should remove the <code>retrolambda</code> dependency. ✂️</p><h4 id=\"variant-api-changes\" tabindex=\"-1\">Variant API changes</h4><p>You may find that there are Gradle API changes that remove certain functionality. One area that has some differences is the variant API, which mean you will no longer be able to manipulate variant outputs. This is due to variant-specific tasks no longer being created at configuration time.</p><p>If you are using the following Gradle syntax, you should check it is still functioning correctly.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">android<span class=\"token punctuation\">.</span>applicationVariants<span class=\"token punctuation\">.</span>all <span class=\"token punctuation\">{</span> variant <span class=\"token operator\">-></span>\n  <span class=\"token punctuation\">...</span>\n<span class=\"token punctuation\">}</span></code></pre><h4 id=\"firebase-plugin-guava-issue\" tabindex=\"-1\">Firebase plugin Guava issue</h4><p>There is a known issue with the Firebase plugin causing a Guava dependency mismatch. It can be easily fixed by excluding Guava from the Firebase plugin. Only add this if it is needed within your project.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">dependencies <span class=\"token punctuation\">{</span>\n  classpath <span class=\"token punctuation\">(</span><span class=\"token string\">'com.google.firebase:firebase-plugins:1.1.0'</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    exclude group<span class=\"token punctuation\">:</span> <span class=\"token string\">'com.google.guava'</span><span class=\"token punctuation\">,</span> module<span class=\"token punctuation\">:</span> <span class=\"token string\">'guava-jdk5'</span>\n  <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">...</span>\n<span class=\"token punctuation\">}</span></code></pre><h4 id=\"robolectric-resources-issue\" tabindex=\"-1\">Robolectric resources issue</h4><p>This won’t affect everyone, however, if you are using Robolectric you may find there is a problem with missing resources. To fix this simply add the following to the <code>build.gradle</code> for your module.</p><pre class=\"language-groovy\"><code class=\"language-groovy\">testOptions <span class=\"token punctuation\">{</span>\n  unitTests <span class=\"token punctuation\">{</span>\n    includeAndroidResources <span class=\"token operator\">=</span> <span class=\"token boolean\">true</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre><h3 id=\"why-should-i-update%3F\" tabindex=\"-1\">Why should I update?</h3><p>There is an endless list of new features and improvements in Android Studio 3.0 and in the new Gradle plugin.</p><ol><li>Kotlin programming language support</li><li>Android profiler: memory, CPU, network</li><li>Java 8 language features built-in</li><li>Faster build times</li><li>Device file explorer</li><li>Instant apps support</li><li>Adaptive icon wizard</li><li>XML and downloadable fonts</li><li>Android Things support</li><li>Layout editor improvements</li><li>APK profiling and debugging</li><li>Layout inspector improvements</li><li>Improved Gradle sync speed</li><li>AAPT2 is now enabled by default</li><li>Firebase app indexing assistant</li><li>App links assistants</li></ol>",
			"date_published": "2017-11-04T00:00:00Z"
		}
,		{
			"id": "https://www.lordcodes.com/articles/hiring-android-developers/",
			"url": "https://www.lordcodes.com/articles/hiring-android-developers/",
			"title": "Hiring Android Developers",
			"content_html": "<p>Since starting my career as a software developer, I have been to interviews at various companies. I have, however, more often been on the other side of the process: reviewing CVs, analysing code submissions and conducting interviews. On a few different occasions, I have been asked how I think the recruitment process should be structured and what is best to look for in Android developers. These questions don't have a simple answer that applies to all situations.</p><p>Hiring (and unfortunately not hiring) many developers across my working life has helped me to shape the way I approach it. I am by no means an expert and still have plenty to learn from others on the topic, but I believe (and hope) I have some valuable insights that may help other people hiring developers. Therefore, I will attempt to write down some different steps you could include in your hiring process.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/vqWLu8uk_F-600.webp 600w\"><img src=\"https://www.lordcodes.com/img/vqWLu8uk_F-600.jpeg\" alt=\"A cartoon candidate taking an Android interview\" title=\"The Android interview\" width=\"600\" height=\"350\"></picture></p><h3 id=\"reviewing-cvs\" tabindex=\"-1\">Reviewing CVs</h3><p>This stage shouldn’t come as a surprise to anyone, as obviously you will need some way for candidates to apply for the position. This is the first opportunity for the candidate to tell you why they think they are right for the job.</p><p>For some people a CV might be self explanatory, but it is pretty amazing how varied CVs can be. Over time I must have reviewed hundreds of CVs and almost every single CV is different in length, style, format and content. I have seen a few <em>killer</em> CVs and unfortunately some that weren’t as good.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/KRHgyJ-A9k-490.webp 490w\"><img src=\"https://www.lordcodes.com/img/KRHgyJ-A9k-490.jpeg\" alt=\"One does not simply write a perfect CV meme\" title=\"CVs are hard\" width=\"490\" height=\"288\"></picture></p><p>When reviewing CVs, it is crucial that you be as fair and objective as possible, avoiding any biases you may have. A good way to achieve this is to compare each CV to the same set of requirements that you have decided are needed to do the job. For an Android developer these may include things like:</p><ul><li>Live apps on Google Play</li><li><em>X</em> years Android development experience</li><li>Performing app releases to Google Play</li><li>Network communication such as consuming REST APIs</li><li>Automation via Continuous Integration services like Bitrise</li><li>Automated unit and UI testing</li></ul><p>If possible try to look for a skill rather than its specific application. For example, knowledge of how to consume a REST API, rather than just whether they mention Retrofit and OkHttp. Obviously if a candidate already knows the libraries you use, this can be a great bonus. The focus should, however, be on spotting their level of experience and their ability to learn new skills quickly.</p><h3 id=\"i%E2%80%99m-not-keen-on-online-tests\" tabindex=\"-1\">I’m not keen on online tests</h3><p>The next stage in the process for many companies can involve some form of online test or screening process such as <a href=\"https://www.codility.com/\">Codility</a>. These tools might make sense for some positions, for example a job that requires intense problem solving or coding quickly under pressure. However, from my experience:</p><ul><li>They are very impersonal.</li><li>They can be time consuming and stressful for the candidate.</li><li>The problems are rarely similar to the type of work the job entails.</li><li>People often do better or worse than they would do in a real-world scenario.</li><li>They only check the solution rather than the journey to get there.</li></ul><p>I'm not saying these online tests are wrong and should never be used. My preference is just to use other ways to find the right person for the role.</p><h3 id=\"remote-%2F-phone-%2F-video-interview\" tabindex=\"-1\">Remote / phone / video interview</h3><p>Once you find a candidate that looks promising it is important to meet them as soon as possible. If the number of applications you are receiving is fairly low you could consider going straight to the on-site interview at this stage. In most situations though you will want a remote interview to take place first.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/wWPm5FGRP7-800.webp 800w\"><img src=\"https://www.lordcodes.com/img/wWPm5FGRP7-800.jpeg\" alt=\"A man running a phone interview\" title=\"The phone interview\" width=\"800\" height=\"581\"></picture></p><p>Remote interviews are usually much shorter than their on-site counterpart, preferably something in the region of 30 minutes or less. The shorter length and the fact they are remote can make them much quicker and easier to schedule with the person applying. They can be a good way to quickly gauge the candidate’s experience, their interest in the position and how well they would fit into the team. By having a conversation, it allows them to form a connection with you and the company. Without this having taken place, if another offer comes from elsewhere they would have a lot less driving them to continue the process with you.</p><p>Importantly, this shouldn’t feel like an interview and should be as informal as you can manage, allowing the candidate to relax. Some potential talking points:</p><ul><li>Their current role</li><li>Working on a particular task</li><li>Code reviews</li><li>Testing</li><li>Continuous Integration</li></ul><p>You may also be recruiting for a completely remote position or prefer to do your interviews entirely remotely for ease.</p><h3 id=\"app-programming\" tabindex=\"-1\">App programming</h3><p>You are looking to hire an Android developer and so the best way to check their technical proficiency is by looking at how they program an Android application. This might seem obvious, but you will find many recruitment processes that rely on object-oriented or functional programming challenges and whiteboard exercises. I gave my stance on online testing earlier, however, there is a key difference here in that the candidate will be programming in Android, using the tools they are familiar with and often in their own time.</p><p>The candidate applying may already have examples of their Android development skills via open source app(s) on GitHub, you could consider looking at these instead to make the hiring process quicker for the candidate.</p><p>If you do decide to ask the candidate to work on an app project of yours, the app should either be very simple so that they can complete it in a reasonable amount of time or it should already be partially developed. You should also make it clear that they can use whatever approach they want and use whichever libraries they wish. This will allow you to see how they think an Android app should be developed.</p><p>There are many advantages to seeing applicant’s Android code before they come in to interview. You can gain insights into their development processes and how they would work as an Android developer. An important consideration though is that completing an app test does increase the amount of effort they have to put in. Therefore, you will have to decide if you think it makes sense for your company to include this in the recruitment process.</p><h3 id=\"on-site-interviews\" tabindex=\"-1\">On-site interviews</h3><p>This will make up the meat of your hiring process and will likely consist of various stages. The main areas you should consider covering are behavioural (team fit) and technical (skill and experience). Before getting started it is a good idea to describe the general format and timings to the candidate. This helps them to understand how much time they have got and what to expect.</p><h4 id=\"have-a-conversation\" tabindex=\"-1\">Have a conversation</h4><p>One way of running an interview is that the candidate sits in front of you and is asked a set of different questions, delivering an answer after each one. This approach would only give you answers to your specific questions and would be unnecessarily stressful for the person you are interviewing.</p><p>Alternatively, I try to make my interviews as conversational as possible. This means leading things in a certain direction using questions, but allowing the candidate to discuss what they want on the topic. This really shows you how the developer would communicate with other team members and allows them to demonstrate their experience and knowledge to you. By making the questions as open as possible, it will expel the notion that there is a single <em>correct</em> answer you are looking for. Instead the candidate should relax and open up, telling you their opinion freely on a particular topic. You will even find you learn about new things during these conversations.</p><h4 id=\"behavioural\" tabindex=\"-1\">Behavioural</h4><p>These types of interviews can often be labelled <em>soft skills</em> or <em>team fit</em> interviews. This should in no way diminish the importance of this area of questioning. If you have put the candidate through the app test already the behavioural component could actually be considered the most important part.</p><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/D5mvA1kfc9-500.webp 500w\"><img src=\"https://www.lordcodes.com/img/D5mvA1kfc9-500.jpeg\" alt=\"Tell me about a time when you prepared for a behavioural interview meme\" title=\"Behavioural interviews need worthwhile questions!\" width=\"500\" height=\"500\"></picture></p><p>You will ask questions which check the candidate fits with your company culture and the team’s way of working. It will also give the applicant some insight into how the company works. As with reviewing CVs, you should decide which characteristics are most important to you when deciding on your behavioural questions. For example:</p><ul><li>Collaboration with other team members</li><li>Ability to learn new technologies and skills</li><li>Leadership qualities</li><li>Communication</li><li>How well they can learn from past mistakes</li></ul><p><picture><source type=\"image/webp\" srcset=\"https://www.lordcodes.com/img/EakkPaAXXB-539.webp 539w\"><img src=\"https://www.lordcodes.com/img/EakkPaAXXB-539.jpeg\" alt=\"What is my worst flaw? I am too awesome!\" title=\"Asking for general weakness may be a waste of time\" width=\"539\" height=\"384\"></picture></p><p>Please don’t ask all the <em>obvious</em> questions we all read about online, such as asking about their strengths and weaknesses.</p><p>Instead finding out about situations where they:</p><ul><li>Had to learn how to use a new library quickly.</li><li>Dealt with a team member who strongly disagreed with their opinion on a code review.</li><li>Persuaded other team members to introduce a different app architecture.</li></ul><h4 id=\"technical\" tabindex=\"-1\">Technical</h4><p>How to run effective technical interviews is a very large and heavily discussed topic. You will also find people have many different opinions of how to go about it.</p><p>It is very common for interviewers to ask you to write solutions to problems on a whiteboard. Personally, I have never understood this approach as developers don’t generally spend their days finding substrings, detecting palindromes and writing code by hand on the wall.</p><p>Any coding you ask the candidate to do should match what they would do if they got the job. This doesn’t mean you have to get them working on the app they would actually work on. It does, however, mean that they work on an Android app, using the tools they would use and in the environment they would work in.</p><p>In reality, developers don’t remember absolutely everything and recall it perfectly on the spot. They sometimes forget the signature for a Compose modifier or the name of the Retrofit annotation they need to use. I think it's a good idea to tell candidates that they can use StackOverflow or the API documentation if they wish.</p><p>When working on an Android app, people use libraries like Coroutines, Retrofit and Dagger. This means when they are coding in the interview I think we should make it clear they can use whatever libraries they want to use. You could choose to force them to write plain Android code so you can check they know how to do it. However, I think it's most valuable to see how they would code in a real-world situation. You may even be able to ask why they chose a particular library or particular approach.</p><p>As I mentioned earlier, any technical questioning should be as conversational as possible. I generally write down a few topics I would like to find out about and then nudge the conversation in the right direction using my questions. For example:</p><ul><li>Handling a slow internet connection</li><li>Automated testing</li><li>Dependency Injection</li><li>Keeping up-to-date with the world of Android development</li></ul><h4 id=\"time-for-questions\" tabindex=\"-1\">Time for questions</h4><p>It is very important that you leave time for candidates to ask you any questions they might have. If the interview was fairly conversational, this may already have been covered. However, if not then it is good to prompt them at the end just to make sure they get the chance to ask any. It is important to remember that you are trying to find the right developer for the team, but they are also trying to find the right company for them.</p><h3 id=\"closing-thoughts\" tabindex=\"-1\">Closing thoughts</h3><p>As I have said a few times, there are various different ways you can check candidates are right for the position. The techniques you choose to use and the questions you choose to ask, won’t be the same as other interviewers. If carefully put together, the process will help you find some really great developers who are a good fit for the team and for the company.</p>",
			"date_published": "2017-07-03T00:00:00Z"
		}
	]
}
