<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Christoffer Winterkvist on Medium]]></title>
        <description><![CDATA[Stories by Christoffer Winterkvist on Medium]]></description>
        <link>https://medium.com/@zenangst?source=rss-b7d8a2928bfc------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*9Ll2oM1ixSox_qo5IJbOHw.png</url>
            <title>Stories by Christoffer Winterkvist on Medium</title>
            <link>https://medium.com/@zenangst?source=rss-b7d8a2928bfc------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Tue, 23 Jun 2026 12:21:00 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@zenangst/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Scripting with Swift]]></title>
            <link>https://medium.com/fink-oslo/scripting-with-swift-c8b929d1a7a3?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/c8b929d1a7a3</guid>
            <category><![CDATA[automation-tools]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[scripting]]></category>
            <category><![CDATA[automation]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Tue, 22 Nov 2022 12:24:27 GMT</pubDate>
            <atom:updated>2022-11-22T12:24:27.123Z</atom:updated>
            <content:encoded><![CDATA[<h4>If you are a Swift developer like me, then it is probably no secret that Swift can be used to produce all sorts of things from macOS-, iOS-, iPadOS-, tvOS-, watchOS apps, command line tools, frameworks to system extensions… Well you name it. If it has an Apple engraved on the back, then it can probably run your Swift code.</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TUTogj-cCWrw4qd8GIhO6w.png" /><figcaption><a href="https://unsplash.com/@carlesrgm">Carles Rabada</a> — <a href="https://unsplash.com/photos/ktWur2xM1hs">https://unsplash.com/photos/ktWur2xM1hs</a></figcaption></figure><p>Overall, Swift is an awesome bicycle for your mind, except for one thing. It is a compiled language, which means that you need to produce a product or binary to get your code to run.</p><p>On the other hand, unix shells like bash, zsh, fish &amp; sh; can run scripts. This can be incredibly powerful because you don’t need to compile, you simply run and it runs for you. Scripts built with any of the mentioned Unix-shells can help you manipulate, customize and automate parts of your workflow which can be a huge timesaver for mundane tasks.</p><p>But there are some caveats, you typically need to context switch because it seldom involves the same language that you usually write code in.</p><blockquote>I’ve lost count of how many times I’ve had to google: “<strong>How to write an if statement in bash</strong>”.</blockquote><p>Wouldn’t it be great if we could combine the two and leverage Swift’s awesome type system and roaring syntax to write our automations without the need to produce a product?</p><p>Just write and run.</p><p>It just so happens that this comes baked in using Swift REPL.</p><h3>So what would scripting with Swift look like?</h3><p>The first thing we should do is to set up a super simple Swift package.</p><p>Sounds like a lot of work, but I assure you, it’s not. We do this to get help from the compiler when we write our script, if we simply open the file using Xcode, it won’t pick up warnings and errors like we are used to.</p><blockquote><strong><em>&gt; mkdir ScriptingWithSwift<br>&gt; cd ScriptingWithSwift<br>&gt; touch Package.swift<br>&gt; touch main.swift</em></strong></blockquote><p>In <strong>Package.swift</strong>, we can create a barebones package called <strong>HelloWorld</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1f35a677e3ad6ea41e65341e14b2455a/href">https://medium.com/media/1f35a677e3ad6ea41e65341e14b2455a/href</a></iframe><p>We set the platform to be <strong>.macOS </strong>and decide which version we wish to be backwards compatible with. To be able to run script inside Xcode, we add an executable target with the same name as the package. We set the <strong>path </strong>to be an empty string so that it searches for swift files in the root folder.</p><p>Let’s do the same for <strong>main.swift</strong> and keep that super simple for now.</p><p>So open the file and add:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/b726c6f2fd3aa79ab62fa5044bced7da/href">https://medium.com/media/b726c6f2fd3aa79ab62fa5044bced7da/href</a></iframe><p>Now open the <strong>Package.swift </strong>with Xcode and run the terminal application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*v3RVEh9PE2M1DGeO8CQ01g.png" /></figure><p>Before we try to run the script in the terminal, there is one little modification we need to do. We need to give the file an executable attribute.</p><blockquote>&gt; chmod +x main.swift</blockquote><p>Easy peasy lemon squeezy, now let’s run the script.</p><blockquote>&gt; ./main.swift<br><strong>Hello, world!</strong></blockquote><p>Alternativly, you can run it via the <strong>swift</strong> binary by typing:</p><blockquote>swift main.swift<br><strong>Hello, world!</strong></blockquote><p>And voila, now it is off to the races.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H4juko_0BQE0pYoLGOcPHQ.png" /></figure><p>If we wanted to, we can execute this script using the built-in app <strong>Shortcuts</strong>.</p><ul><li>Open Shortcuts and create a new shortcut.</li><li>Choose <strong>Terminal</strong> as the command.</li><li>Copy-paste the exact path to your script and click <strong>run</strong>.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G0x6oN2dki0Jt__cF8etIQ.png" /></figure><p>This is where I leave you, but before we do, let’s summarize what we have done and end with some inspiration.</p><h3><strong>To summarise what we have done:</strong></h3><ul><li>We leverage Swift Package Manager to get a sane environment to write our scripts in, which is backed by the all-mighty Swift compiler, right there at your fingertips.</li><li>We made the script executable from the Terminal or any other application or service that can run scripts</li><li>Added our freshly brewed script to <strong>Shortcuts</strong> so that we can have instant access to it and run it at our leisure</li></ul><h3>So, what can we do with Swift scripting?</h3><p>Well, it just so happens that with the release of Swift 5.7, you now gain the full force of structured concurrency at the top level which makes it ridiculously easy to fetch information from an API and manipulate the data before processing or presenting it somewhere else.</p><p>We can run apple scripts to control UI on macOS or even run other shell scripts or unix commands.</p><p>I’ve used it to tweak features in Ventura by changing settings in Stage Manager with the push of a key. You can find more info about that here:</p><ul><li><a href="https://github.com/zenangst/HideDockAndStageManager">GitHub - zenangst/HideDockAndStageManager</a></li><li><a href="https://github.com/zenangst/StageManagerAppWindowGroupingBehavior">GitHub - zenangst/StageManagerAppWindowGroupingBehavior</a></li></ul><p>The possibilities are endless.</p><p>If you made it to the end and still feel like you came up empty-handed.<br>Here is a picture of an adorable kitten.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cuVpGWbB8xK-pEN7xxQiDw.png" /><figcaption>Loan — <a href="https://unsplash.com/photos/7AIDE8PrvA0">https://unsplash.com/photos/7AIDE8PrvA0</a></figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c8b929d1a7a3" width="1" height="1" alt=""><hr><p><a href="https://medium.com/fink-oslo/scripting-with-swift-c8b929d1a7a3">Scripting with Swift</a> was originally published in <a href="https://medium.com/fink-oslo">Fink Oslo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Seaworthy mobile applications know how to navigate]]></title>
            <link>https://medium.com/fink-oslo/seaworthy-mobile-applications-know-how-to-navigate-f3e23a423f43?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/f3e23a423f43</guid>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[navigation]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Thu, 21 Apr 2022 07:53:41 GMT</pubDate>
            <atom:updated>2022-04-21T07:53:41.565Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pdy986yuHcqr7GjbWKkHUQ.jpeg" /><figcaption>alonsoreyes <a href="https://unsplash.com/photos/mG_rp41aYqM">- https://unsplash.com/photos/mG_rp41aYqM</a></figcaption></figure><p>Ahoy fellow buccaneers! You might have been in this game a long while or you might just be starting out, whichever rings true, I think we can agree that the following statement is universally true for mobile applications:</p><blockquote>I reckon we can all agree that navigation be a cornerstone o’ any application. We often loot it fer granted ‘n don’t really try t’ scale it ’til th’ needs occurs which often comes as a curveball ‘n gives us wee time t’ iterate or optimize.</blockquote><p>I think that is quite enough pirate speak for one blog post 🏴‍☠️<br>What I intended to say was:</p><blockquote>I think we can all agree that navigation is a cornerstone of any application. We often take it for granted and don’t try to scale it until the need occurs, which often comes as a curveball and gives us little time to iterate or optimize.</blockquote><p>What if we took a different approach to navigation and thought about it as a feature rather than a system-provided action. This article is not meant to force you into a direction, the following will show abstract implementations written in Swift and is meant as inspiration rather than forcing your hand. Keep in mind that new technologies like SwiftUI will flip the table, with that said there are still lessons to be learned here even if you are bleeding edge.</p><p>Don’t let the Swift language throw you off, the things we are going to go through here can be applied to other platforms with the help of your imagination.</p><p>What this means is that if the examples contain any holes, it is up to you to fill them in based on your current requirements, constraints, and needs. However, we will try to add some inspirational new features that you might not have thought about earlier that can open new doors when it comes to developing your application.</p><p>We can start by making a small list of criteria and requirements for making the feature successful both for our users and ourselves.</p><h3>Mission statement aka pirate manifesto</h3><ul><li>Should be type-safe</li><li>Decouple and create clear boundaries between features</li><li>Benefit the users and the developers</li><li>Increase re-writability of our application</li></ul><p>What makes navigation type-safe and why is it important? Well, if we play our cards right, this should add clarity to our navigation stack as both new and old developers should be able to figure out how UserA got from A to Z.</p><p>And what about decoupling, why is that relevant? Imagine having a ship with the bolts wedged together, it will make it unnecessarily hard to make repairs. The same goes for your application, with clear boundaries, it will be easier to repair or refactor (whichever word floats your boat).</p><p>The last two points are more side-effects and we will get to those later in this article. If things still sound vague, don’t worry, let’s get the show on the road so that we gain more clarity.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ikWY4ihvkpQFlIrkmX8rFQ.jpeg" /><figcaption>tjump<a href="https://unsplash.com/photos/rkFIIE9PxH0"> - https://unsplash.com/photos/rkFIIE9PxH0</a></figcaption></figure><h3>Destination</h3><p>Let us start with a very basic model, we will start with making an enum and giving it a proper name. When we navigate the seven seas, we want to be able to put an X on the map to illustrate where we are going, however, X doesn’t make for a very descriptive model name so lets instead go with Destination. Yeah, I think that will do nicely. So our barebones model will look something like this.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1980eee1e87ec3f99bebcc261611309e/href">https://medium.com/media/1980eee1e87ec3f99bebcc261611309e/href</a></iframe><p>Tidy. Now let us plot some <strong>X</strong>:es into our application.</p><p>But before we do that, let us take a quick step back and think about why an enum would be an appropriate choice instead of a regular struct or class. Enums are bound to a finite set of cases which would translate perfectly to our applications navigation stack as it is also finite. Enums are also super easy to extend by simply adding more cases to them. In addition, at least for the case of Swift, we can add one or more associated values to each case. This is super useful if we need to pass information from one place to another.</p><p>From a developer perspective, when using a decent editor, we will get code completion for all available cases which are both great for discoverability and overall developer happiness.</p><p>Last but not least, when we intend to use the enum, we do get the option to either unwrap the current value using an if statement but the preferred way would be to simply switch over the enum to cover all the cases for our current use case (pun intended). So if we leave one case unfulfilled, it will result in a compiler error rather than a runtime crash.</p><p>Can you smell that? That is the delicious fragrance of type-safety that we aim for, let us keep cooking!</p><p>This would tick off at least three (if not all) boxes in our mission statement.</p><p>To make this a bit less abstract and more fun, imagine that the application that we are building is a Pirate trading app, let’s call it Pirate Bay.</p><p>The user… err I mean… the scoundrel (or scruffy-looking nerf herder for all our space pirates out there) should be able to do the following:</p><ul><li>Have a home screen, a place to collect their thoughts and get an overall overview of current trades, etc.</li><li>Scout the marketplace for treasures</li><li>Look at individual items</li><li>Check sellers and buyers profiles</li><li>Manage their profile</li><li>A login page</li><li>A log out action</li><li>Download user information</li><li>And last but not least, a way to opt-out from the service</li></ul><p>(Even if we are pirates, we need to align ourselves with GDPR to avoid walking the plank)</p><p>So let us take a look at what that might look like by extending our Destination enum.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c90eebc3c5834eff873ca9af8c90c58/href">https://medium.com/media/1c90eebc3c5834eff873ca9af8c90c58/href</a></iframe><p>That looks pretty neat.</p><p>By glancing at the enum, we get a sense of the size of our application. And if we are completely foreign and this is the first time we open the project, we can even read out the purpose of the app, all without adding a single comment to our very bare-bones implementation. Now that is some self-documenting piece of treasure right there.</p><p>But there is one thing that breaks the type-safety, can you spot it? Take a second before you continue, what could potentially go wrong here?</p><p>Both the item and profile case take raw String as its associated type, this could potentially lead to situations that we don’t want. Take for example if we try to navigate to an item using a profile identifier, this really shouldn’t happen, but with the current implementation, it could. Even if that would be highly unusual.</p><p>I’ve jinxed myself far too many times by uttering the following words: “That would never happen”.</p><p>So before we continue, let us quickly look at how that could potentially be fixed by taking our type safety to the next level and earning ourselves the pirates badge of honor.</p><p>The fix isn’t that hard to apply, we simply need to wrap our string-based navigation in another value type that is unique to that case (this might be a tad unique to Swift, but bear with us).</p><p>So instead of using String, let us introduce our value types, one for each case.</p><p>Here are some appropriate new types for our pirate application:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/17224067543c5f79cb5544a156b299a9/href">https://medium.com/media/17224067543c5f79cb5544a156b299a9/href</a></iframe><p>With the new types in place, let’s update our enum.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/59ef61da5ecb486abe83c645d699652e/href">https://medium.com/media/59ef61da5ecb486abe83c645d699652e/href</a></iframe><p>If we want to extend this even further, both Loot &amp; Pirate could be protocols, that way our cases could tackle polymorphism without growing out of proportion and eventually becoming a Kraken.</p><p>Now that we know where we are going, we need someone to take us there. This brings us to the next piece of the puzzle.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*QG60_RJS3tJC6nTYjIZ1rA.jpeg" /><figcaption>seshareddy — <a href="https://unsplash.com/photos/Go5qDQJQSU4">https://unsplash.com/photos/Go5qDQJQSU4</a></figcaption></figure><h3>Navigator</h3><h4>Every good ship needs a good captain</h4><p>As many of you already know, vanilla navigation is done by either presenting on top of a view controller or relying on UINavigationController being the parent of your view controller.</p><p>Let’s take this vanilla example where we have a list of pirates and when you tap a pirate entry, you should display the details for the selected pirate. It might look something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a07b646e96e871779f27e7713cb55855/href">https://medium.com/media/a07b646e96e871779f27e7713cb55855/href</a></iframe><p>This works fine, however, remember rule number two in the pirate manifesto:</p><p>You don’t talk about pirate club, ops! … wrong franchise, I meant: Decouple and create clear boundaries between features, savvy?</p><p>As seen in the example, ListViewController needs to know about DetailViewController and its requirements. At first glance, this might not feel like a huge deal, the example isn’t a lot of code, but trust me land crab, the seas can be stormy and unfriendly. So when your application grows, and it will, you can quickly find yourself running out of ink while drawing your map. Making it feel hopeless to untangle, refactor, redraw or provide additional routes. Almost like working with something that is edged in stone, and we don’t want that.</p><p>So for our pirate application, we need the best of the best. We need the Navigator!</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/beef0521818963285016f54510861ce5/href">https://medium.com/media/beef0521818963285016f54510861ce5/href</a></iframe><p>It doesn’t look like much yet so let’s fill in some blanks. As mentioned, the way to perform navigation is by using UINavigationController, so we will need one of those aboard our ship. However, we don’t need to expose that in our public API, the features shouldn’t really care as this is an implementation detail for our top dog class but alas one is needed.</p><p>Now that we have an opportunity to provide a solid public API for our app’s cornerstone, let’s make it easy enough that we can still reason about it even after a night of grog and looting.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f0f2d260ad9cc702a0a1c2af7c370d05/href">https://medium.com/media/f0f2d260ad9cc702a0a1c2af7c370d05/href</a></iframe><p>We now have a super-easy way of handling navigation for our list and detail example, but before we move on, Let’s just take that example and apply our Navigator to it.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/7d74bacbd66c4a8a45825ac8e877d409/href">https://medium.com/media/7d74bacbd66c4a8a45825ac8e877d409/href</a></iframe><p>This example didn’t save us a lot of lines of code, but that is also not the point. What we did gain from this approach is that ListViewController no longer knows about DetailViewController without losing the ability to perform navigational tasks. In addition, just by reading the instance variable definition of the class, we can see without looking at any function bodies that this class can perform navigational tasks. This is highly underrated and the benefits become clearer as your code grows but the clarity of the controller will remain. The same might not be as true for the vanilla example that lacks the reference.</p><p>As for increased refactor-ability (if that is even a word), we could refactor the DetailViewController in isolation, without having to change anything in our ListViewController, as long as the contract between the view controller and use of Destination stays intact.</p><p>So far we have checked off the following criteria:</p><p><strong>Type-safety </strong><br>Leveraging from enum with associated value types, we can ensure that both ends uphold a contract when handing off information between controllers. It also defines a finite set of destinations that paints a beautiful map of our application.</p><h4>Decouple and create clear boundaries</h4><p>Adding the Navigator into the mix and giving it full control over what to present and where, offloads any excess knowledge that the controller used to have, just to get to where we were supposed to go. We can go as far as to state that navigation is a “fire-and-forget” type of deal for our controllers, which is well within the boundaries for any sea roaming scoundrel.</p><h4><strong>Increase re-writability of our application</strong></h4><p>By having clear boundaries between the cornerstone foundation and the features of the application, there is less to rewrite and fix up because we have fewer places where we create new instances of classes and structs.</p><h4><strong>Benefit the users and the developers</strong></h4><p>As developers, we gain type-safety, a more scalable foundation, something that is easier to rewrite or reroute. Everything mentioned should ultimately lead to a better application where there is more time to focus on the details.</p><p>This is all great, but I think that we can do better, don’t you?</p><h3>For the users</h3><p>Let’s revisit our previous implementations to see if we can’t take this to the next pirate-level.</p><p>All good things are three, so lets focus on the following things when trying to improve our already awesome application.</p><ul><li>State restoration</li><li>Deep linking</li><li>Improved crash reports</li></ul><h4>State restoration</h4><p>One feature that can set an application apart is the use of state restoration. So when the application is manually closed by the user or forced quit by the system, the previous application state can be obtained and restored when the application is launched again.</p><p>In order to do this, we need something that can represent the bread-crumbs of the navigation steps that we can perform throughout the application. Luckily for us, we have Destination that holds their own unique value and can be translated into a navigation action. There are multiple ways to skin a ferret but the sake of simplicity and not to argue one is better than the other, let’s just make this happen with the built-in Codable protocol.</p><p>Conforming with our current example is super easy, we simply add Codable to all of our current models, like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f7ee5fd3466895d58175d5fb44550724/href">https://medium.com/media/f7ee5fd3466895d58175d5fb44550724/href</a></iframe><p>We now gain the ability to both encode and decode individual or collections of Destination’s.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/633b38c37130edd689144e78b4322d05/href">https://medium.com/media/633b38c37130edd689144e78b4322d05/href</a></iframe><p>It couldn’t be easier, and we can now pick if we want to store it as Data or String. We can also decide if we want to store it in UserDefaults or directly to disk, both are valid options.</p><p>This is only the first part of the puzzel, we also need to keep a source of truth of the current navigation stack so that the application can save it at a moment’s notice. A natural place to keep this current stack is on the Navigator. Let’s modify it ever so slightly just to populate the collection of Destination’s when a navigation action is performed:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/335174956f22e8697c1872edf0c3f542/href">https://medium.com/media/335174956f22e8697c1872edf0c3f542/href</a></iframe><blockquote>“wolde you bothe eate your cake, and have your cake?”</blockquote><p>Easy-peasy pirate squeezy. But wait, we also need to update the current stack when the user pops view controllers of the screen. Sadly, there are no good delegate calls on UINavigationController to hook into, but fear not dear sea captain, we can leverage from inheritance which can let us have our cake and eat it too.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e3825187bcef66777f19fe629553fd82/href">https://medium.com/media/e3825187bcef66777f19fe629553fd82/href</a></iframe><p>Now, all we need is to use this freshly brewed class and become the delegate, back to the Navigator:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c7349d6ca746d97ebce9d5ed1034f270/href">https://medium.com/media/c7349d6ca746d97ebce9d5ed1034f270/href</a></iframe><p>A tad more code but now we route all invocations of both push and pop to our Navigator so that it is always in sync. From here on, it is up to you to find the best fit for your application on where you want to store and restore the navigation stack as your application relaunches.</p><blockquote><em>“Kill two parrots with one stone”</em></blockquote><h4>Deep linking</h4><p>Let us move on to the next bonus feature, which is deep linking. Right now, our navigator can only open one Destination at a time based on the current API. So by adding one convenience method on Navigator, we can improve the call-site implementations by providing a new function that takes a collection of Destination’s. This method may look something like this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2e2ddde66eff1ca339f1f50a16fd31ed/href">https://medium.com/media/2e2ddde66eff1ca339f1f50a16fd31ed/href</a></iframe><p>So if we wanted to build up the entire stack again, we can simply call it with X amount of destinations and voilá, we now have the same view hierarchy as before.</p><p>As for navigating using a URL scheme, well here you need to implement your own string parsing methods that will return the correct destination or destinations based on the URL. When those method(s) have produced the correct output, then simply pass the result into the newly created function.</p><h4>Improved crash reports</h4><p>Based on the state restoration and the way you implemented deep linking, we can now sprinkle a bit of extra spice into our crash reports, and provide a set of deep links that the application can interpret. If we attach these to crash reports, we get both breadcrumbs and a way navigate in the same way as the user did up until the crash occurred. This can give you great insight into what was going on before your ship got blown out of the water, and relying what happened can even help pinpoint the exact location where the first cannon ball hit the hull.</p><p>I hope this was helpful and I can’t wait to see what glorious vessels you will produce in the future.</p><blockquote><em>When I was one,<br>I sucked my thumb,<br>The day I went to sea.<br>I climbed aboard a pirate ship<br>And the Captain said to me:<br>‘We’re going this way, that way,<br>Forwards<br>backwards,<br>Over the Irish Sea.<br>A bottle of rum to fill my tum<br>A Pirates’ life for me’.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/480/1*cy5lUGAlV-yNz0g8octbbw.gif" /></figure><p>Have a good one Mateys!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f3e23a423f43" width="1" height="1" alt=""><hr><p><a href="https://medium.com/fink-oslo/seaworthy-mobile-applications-know-how-to-navigate-f3e23a423f43">Seaworthy mobile applications know how to navigate</a> was originally published in <a href="https://medium.com/fink-oslo">Fink Oslo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Code Injection In Swift]]></title>
            <link>https://medium.com/itch-design-no/code-injection-in-swift-c49be095414c?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/c49be095414c</guid>
            <category><![CDATA[development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[hot-reloading]]></category>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Wed, 30 May 2018 19:06:06 GMT</pubDate>
            <atom:updated>2018-05-30T19:08:34.963Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cilSzn9bDTB7iOXiV9ok3g.png" /></figure><h4>One feature that iOS purists envy and the primary argument for alternative solutions to Swift is code injection or as others like to call it, hot reloading. It cuts down development significantly as you don’t need to recompile to see your changes. For developers that work closely with designers or have issues visualizing the result beforehand, it can be a game changer.</h4><blockquote>“With hot reloading, you can even run new code while retaining your application state. Give it a try — it’s a magical experience” — React Native README</blockquote><p>Personally, this is feature is what makes React Native great. I know, there are more features that React Native (or insert any other alternative here) possesses but right now we are talking about code injection so bare with me. It opens up for being able to test different states at a glance; and with all the time it saves, you can focus on what matters, the things that set your app apart from its competitors.</p><p>So what if I told you that you could achieve hot reloading without jumping ship. A bright gentleman named John Holdsworth has made an application called Injection (not to be confused with dependency injection). The app is available for free in the Mac App Store.</p><p><a href="https://itunes.apple.com/no/app/injectioniii/id1380446739?mt=12">InjectionIII on the Mac App Store</a></p><p>The application lives in the menu bar and observers whatever Xcode project you tell it to monitor. So the gist is that any file that changes will recompile and injected into your running application. What is does under the hood can feel quite magical, mainly because it is. John has done a great job of describing the process, and if you are feeling adventures, you can always jump into the source code as it is available on GitHub.</p><p><a href="https://github.com/johnno1962/InjectionIII">johnno1962/InjectionIII</a></p><p>Before we go any further, I just want to note that injection only works in the simulator, I suggest you build in the simulator and test on a device.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RAy6UCAOeqN1bbcbkrhGRw.png" /><figcaption>Code injection vs. Playgrounds</figcaption></figure><h4>Playground-driven development that was made famous by the fantastic team at Kickstarter put a tremendous spin on app development. It meant that you could manipulate the state of your application without the need to rebuild and rerun it.</h4><p>Each screen could have their playground so that you could quickly test and work with all states related to that screen in isolation. However, because the technique is dependent on your app being compiled as a framework, it means that you will have to recompile before you see your code changes appear. Playgrounds can be fast or slow depending on the apps sizes, my biggest concern with this approach is not the setup or the hurdles you need to jump over but rather the core stability of playground themselves.</p><p>The concept of playgrounds is excellent, being able to run and test code without the weight or overhead of a project. Sadly, it does not always deliver. If you are buying into playgrounds and using them for development, make sure you learn all the tips and tricks as you will find yourself in scenarios where you need to turn to blood magic to understand what is going on and more importantly, get it to work again.I don’t want to downplay anything that the Kickstarter team has done because they indeed have created magic. I’m not saying that Injection is superior or the defacto way here, but in my personal experience, it has always delivered why more stable results than playgrounds ever have.<br>Just like playgrounds, if you want to leverage for its full potential then learn how it what it does, how it works and what limits it has. I would recommend to read up on both techniques, find the one best suited to you. Perhaps combine them and create something truly magical.</p><p>There are some limitations with injection, one of them being that you cannot inject structs, extensions or final classes. Once you get past this, there is still a lot you can do to decrease your development time. For me, there are multiple entry points where injection truly shines, here are a couple of them.</p><blockquote>The examples use Vaccine to set up injection.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W5XxBwj5nAS0lgoRIDhCjg.png" /></figure><h4>To get the most out of code injection, you need be able to provide your application with a new instance of the class that you are injecting. A good point of entry for injecting code is to reinitialize your app at the application delegate level.</h4><p>It increases the likely-hood of getting the desired effect of code injection as your root objects are recreated using the newly injected code. It also provides with a point of entry for displaying the target view controller(s) that you are modifying.</p><p>So what it means in practice is that you can push or present the relevant view controller directly from your application delegate cutting out the need to recreate the view controller stack by manually navigating to the view controller you are editing. Working with InjectionIII is very similar to how playground-driven works, without having to wait for the playground to load or recompile your app as a framework.</p><blockquote>The devil is in the details and for every second saved, you get additional time to apply polish.</blockquote><p>When applying injection to this app layer, you are free to change the bounds of the window which means that you can set the bounds to be a different device size. This opens up for testing multiple devices using the same simulator. Kickstarter has done a lot of great innovation in this area, so I suggest you head over and take a peek at what they did.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/3033d4b6cd80ee7717532862ee099f30/href">https://medium.com/media/3033d4b6cd80ee7717532862ee099f30/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9VXgjrAhY0rZs0zxHp5mWQ.png" /></figure><h4>There is no secret that the majority of the work that we do usually end up in a view controller. That is probably the main reason for us often ending up with massive view controllers, but that is an unrelated topic.</h4><p>The good thing with about view controllers is that you can quickly create a system around them because of the view lifecycle it inherits. Most of the set up for our view controllers happen in viewDidLoad. Because of this reason, we can do some preprocesses to clean up before we invoke the method again. What this means is that we can change our set up instructions and invoke them again and see the new behavior appear on the screen.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/63d5a40b59737600b10a17d115182b5a/href">https://medium.com/media/63d5a40b59737600b10a17d115182b5a/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0aGc63ppUL7ZI6_Db_46qA.png" /></figure><h4>Working with views is relatively similar to view controllers, except that they don’t inherit the view lifecycle as view controller does.</h4><p>So here we need to do some additional work to introduce a streamline. When doing vanilla programming you do a lot of work in the initializer, the issue here is that you can’t invoke the initializer again as it will only run once for the lifetime of a view.</p><p>The most straightforward fix is to create a method that is invoked directly inside of the initializer. The same method is then used as the responder for the injection notification. When wired correctly, we can change the code inside our view’s load method and set the changes reflected on the screen.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/2aae7e9028ea78900d149a288767f61e/href">https://medium.com/media/2aae7e9028ea78900d149a288767f61e/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2RPbHqcG-egNN-xPtDgf5w.png" /></figure><h4>Because we don’t always create new instances of our views, we could end up in a scenario where we add additional constraints that will render the views layout constraints ambiguous.</h4><p>The reason is that we add constraints that are conflicting or duplicated which the layout engine cannot figure out how to make satisfiable.</p><p>Fixing it does not take a lot of effort, you need to do your book-keeping by storing your views constraints in an array. When the load view method runs, we need to deactivate or remove the previous layout constraints before we add the new ones.</p><p>Take a look at the view example for details on how this could be implemented.<br>If you add new constraints on line 22, activate them and later store them in the layoutConstraints array, this should help to fix any ambiguous constraint warnings from occuring.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lzWKVm-I1WrePNi0T6RiMw.png" /></figure><h4>Making great animation sequences relies heavily on fine-tuning. What sets a great and tailored animation apart from using a regular UIView animation block is usually the fact that more love is put into having great timing.</h4><p>You can learn a lot of tips and tricks on what generally looks good, but there is no one-size fits all if you want to stand out. You need to iterate to make the animation fit with the apps tone of voice.</p><p>When applying injection with animations, it helps to think about your code like an orchestra. Set the stage and use your injection point, the method that will be called when the file is injected to both reset the stage, cleaning up previous animations and applying new ones and watch your orchestra play your masterpiece. That way you can sit together with your fellow designers and together decide what looks and ultimately feels right.</p><p>You can also reset your animations by injecting your view controller.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1c09455bf87242907291d288aba4140a/href">https://medium.com/media/1c09455bf87242907291d288aba4140a/href</a></iframe><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eAnkUWfUARfHqX4Yv_IfrQ.png" /></figure><h4>Code injection can easily be applied to your data sources. Just like all your other objects, you need to listen to incoming notifications and reload with the same data that you already have when one arrives.</h4><p>The easiest way is to call reloadData on your collection view or table view, that will invoke your cellForItemAt indexPath: IndexPath method and configure your cell with the newly injected code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1ba62a6052e1787dc9d3225ce6c4834e/href">https://medium.com/media/1ba62a6052e1787dc9d3225ce6c4834e/href</a></iframe><h3>Debugging or live patching</h3><p>Logic should be unit tested, and I can’t stress that enough. But there are situations where you quickly want to check the rendering of a state to see what happens if x is equal to y and not z and vice-versa. Layout algorithms can also be a lot easier to reason with using live results rather than simple unit testing, depending on what kind of person you are.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fDIoYQr8QHCMn8q1BQy-jg.png" /></figure><h4>As a developer, it is your job to create an environment where you and your fellow designers can work together. The set up will define how rapidly you allow your team to move.</h4><p>Minimizing the number of times, you need to recompile your app you open up for more fine-grained tuning of things like; animation timings, tweaking fonts, colors, line-heights or changing layout constraints. Anything that you or your designer friends want to iterate over.</p><h3>Competitive advantage</h3><p>Thinking outside the box and continuously improving your tools and best practices can give you a competitive advantage. Having great tools can also work as a stress reliever as repetitive or mundane tasks are more easily handled, it opens up for collaboration and fast iteration which will have a positive effect on the end product. The devil is in the details and for every second saved, you get additional time to apply polish.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XT-CD2w1eQ0YtdRBPl2KgA.png" /></figure><h4>Because injection works using notifications, there is some additional setup needed to get the desired output that you want.</h4><p>To make things easier, I created a series of templates that have injection already enabled. Using templates can help you streamline the way you build views, controllers, models, etc. Templates are great for more than just adding injection</p><p>I strongly encourage creating your templates and incorporating them into your workflow.</p><p><a href="https://github.com/zenangst/Xcode-Templates">zenangst/Xcode-Templates</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WDQ-5yHeG3dlGCBWjd6uNg.png" /></figure><h4>I’ve been working a lot with injection over the years, and it has become an essential part of my workflow. So crucial in fact that I’ve invested time into making a framework to provide more natural way to implement injection in new or existing projects.</h4><p>Seeing as there are different ways to use injection depending on which component you inject, different rules should apply.</p><p>Vaccine provides an easy way to load the injection bundle in your application delegate, has view controller extensions for recreating the view controllers hierarchy and necessary sugars on top of NSObject.<br>The framework does its best to cover all the areas mentioned above in a lean and straightforward way yet keeping it maintainable.</p><p>Vaccine is available via CocoaPods; you can find the repository here:</p><p><a href="https://github.com/zenangst/Vaccine">zenangst/Vaccine</a></p><p>Maybe injection is not for you, but you don’t know that unless you tried. If you find any neat ways of implementing this, be sure to hit me up on Twitter (<a href="http://twitter.com/zenangst">@zenangst</a>) as I’m super passionate about the subject. Also be sure to give a shoutout to John Holdsworth (<a href="http://twitter.com/Injection4Xcode">@Injection4Xcode</a>) as this wouldn’t even have been possible without his genius mind and all the hard work he has poured into the tool.</p><p>I want to end this article with a twitter quote from John Holdsworth himself.</p><h3>Injection for Xcode on Twitter</h3><p>Still not &quot;Hot Reloading&quot; #swiftlang in your #Xcode projects? You&#39;re running out of excuses.. InjectionIII is now available in the Mac App Store 😎 https://t.co/3bvr9fXgSp</p><p>Thanks for reading!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c49be095414c" width="1" height="1" alt=""><hr><p><a href="https://medium.com/itch-design-no/code-injection-in-swift-c49be095414c">Code Injection In Swift</a> was originally published in <a href="https://medium.com/itch-design-no">itch design</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to stop leaking information through multitasking]]></title>
            <link>https://medium.com/itch-design-no/how-to-stop-leaking-information-through-multitasking-215207760c31?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/215207760c31</guid>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[security]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Mon, 23 Apr 2018 06:12:49 GMT</pubDate>
            <atom:updated>2018-04-23T06:12:49.770Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1DFuNqfpnIErP7AeBHqDew.jpeg" /><figcaption>John Moeses Bauan — <a href="https://unsplash.com/photos/2zUWGeg8DTw">https://unsplash.com/photos/2zUWGeg8DTw</a></figcaption></figure><p>When we talk about security about iOS application, we usually think about things like SSL certificates, storing information securely in the keychain, etc. <br>This is all good, and it is super great that we have such a wide focus on these days. However, there is one small culprit that a lot of app makers seem to overlook, and I don’t blame them.</p><p>I’m talking about the multitasking feature that is built-in to the operating system. So what makes it a culprit? Well basically, if the user decides to leave your application, the operating system will take a snapshot of the current view controllers current state and save it as the placeholder for your application. But what if the screen that you just left has some personal information about you that you don’t want to leave the application. Maybe you’re using a bank application, and a colleague or friend borrows your phone, she or he will be able to read parts of the information that you last look at using that app. It might sound like I’m over exaggerating or making an issue out of a non-issue. Maybe, maybe not. All I know is that if I use an application that stores personal or sensitive information, I’d want it to stay within the application and not leak in any way, shape or form.</p><p>So, this is what we did to dash a bit of extra added security to our application.<br>Because we didn’t know exactly which screen should be secure or which would be fine to show, we took the path which tried to secure the entire application. Here is what we did.</p><p>When building iOS applications, you need to provide an application delegate. This class has methods that get invoked when the context changes for our application. The two scenarios that we will listen to using our application delegate are:</p><ul><li><strong>func</strong> applicationDidBecomeActive(<strong>_</strong> application: UIApplication)</li><li><strong>func</strong> applicationWillResignActive(<strong>_</strong> application: UIApplication)</li></ul><p>You probably already know as much and even if you don’t; you can probably guess when these methods are invoked. The first one gets invoked when our application became active and the latter one will be invoked when the user is leaving our application.</p><p>So to dash a bit of added security we will simply cover the current window with a blurred view so that prying eyes won’t see what is being displayed on the screen. Using blur is not the safest option, but for the time being, we only want to keep people out that have direct access to the phone while someone is borrowing it. If you want additional security, you could display the applications launch screen or a picture of a cat; it’s up to you.</p><p>Enough talk, lets look at the code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d5e16df4206ce6adb8fdf397daf61157/href">https://medium.com/media/d5e16df4206ce6adb8fdf397daf61157/href</a></iframe><p>As you can see, it is not a lot of code to make a barrier that blurs whatever is on screen. When the application resigns its active state, we add the visual effects view to the root view controllers view. We animate the alpha value to make the transition buttery smooth. When the application becomes active again, we reverse the animation and finally remove the visual effect view from the view hierarchy. You can play a bit with the blur effect to make it match your applications look and feel, we went with <strong>.light</strong> for this demo as it worked best with the background.</p><h4>End result</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/745/1*8tU8Qh6YA76y8r9Vbf_YWw.gif" /></figure><p>Remember that just adding this little bit of security is not enough, you probably want to add a pincode screen and do all the other security related tasks that you normally do. This is just to stop your app from leaking information to the multitasking feature on iOS.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=215207760c31" width="1" height="1" alt=""><hr><p><a href="https://medium.com/itch-design-no/how-to-stop-leaking-information-through-multitasking-215207760c31">How to stop leaking information through multitasking</a> was originally published in <a href="https://medium.com/itch-design-no">itch design</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating your own templates in Xcode]]></title>
            <link>https://medium.com/itch-design-no/creating-your-own-templates-in-xcode-98a08bf20038?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/98a08bf20038</guid>
            <category><![CDATA[xcode]]></category>
            <category><![CDATA[productivity]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Sat, 21 Apr 2018 09:40:42 GMT</pubDate>
            <atom:updated>2018-05-29T07:38:36.078Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kXZkiCXa-0Dbv5w9QmF2ug.png" /></figure><p>When developing applications, there are loads of tools and techniques that can help you save time and make you more efficient. One such tool is templates, little snippets that give you a more concrete starting point for what you want to achieve. Xcode comes with some built-in templates but templates truly shine when you tailor them to your code style, pattern and other personal preferences. Lucky for us, Xcode supports this, but getting it set up can sometimes feel like practicing voodoo magic as Apple neglect to promote this hidden gem, and we result to blog posts to figure it out.</p><h3>Creating your templates folder</h3><p>Xcode looks for templates inside ~/Library/Developer/Xcode/Templates.<br>This folder does not exist out of the box so you will have to create it manually.<br>You can do that in the terminal by running the following command:<br>mkdir ~/Library/Developer/Xcode/Templates<br>Or navigate to your Xcode folder in Finder using <strong>⇧⌘G</strong> — “Go to folder” and paste ~/Library/Developer/Xcode/</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/256/1*pi6iMd9Sxm0ADE9DnnxmpQ.png" /></figure><p>Inside your newly created templates folder, you can create subfolders to categories your templates. <br>At the time of writing, I went with one folder called <strong>Custom.</strong></p><p>A good starting point for creating templates is to duplicate one of the existing ones. I’ve made my templates based on the Swift File.xctemplate</p><p>You can find it here:</p><blockquote>/Applications/Xcode.app/Contents/Developer/Library/Xcode/Templates/File\ Templates/Source/Swift\ File.xctemplate</blockquote><h3>Creating your template</h3><p>Xcode templates have their own file type called .xctemplate.<br>It works as a container for all your template related files.<br>A basic Swift template consists of four files.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/706/1*5d4JxmOjtG-KwdO_vpM-HA.png" /></figure><ul><li><strong>TemplateIcon.png<br></strong>This icon will be used in the template selector.</li><li><strong>TemplateIcon@2x.png<br></strong>Same as TemplateIcon.png but is used on Retina Mac’s.</li><li><strong>TemplateInfo.plist<br></strong>The property list holds additional metadata about your template, such as description, summary, kind, etc.</li><li><strong>__FILEBASENAME__.swift<br></strong>This is the template file that you will customize to fit your needs.</li></ul><p>The <strong>__FILEBASENAME__</strong> placeholder will be replaced with whatever you input in the template picker; this can also be used inside your template.</p><p>Here is what a simple UIView template could look like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/21127873d03624dd263f5751c463ff81/href">https://medium.com/media/21127873d03624dd263f5751c463ff81/href</a></iframe><h3>Snippets in templates</h3><p>One thing worth mentioning is that you can use templates in combination with snippet placeholders. If you are familiar with the concept of Xcode snippets, you’ll know that for a specific snippet you can add placeholder tags that the user can navigate between and replace with the actual code. This helps speed up the process and makes your templates easier to work with.<br>You can add snippet placeholders to your templates by inserting them as <strong>&lt;#MyPlaceholder#&gt;</strong>. This will then be replaced with a macOS token element.</p><h3>Examples</h3><p>To share some inspiration, here are a few of my templates that I use on a regular basis.</p><h4>Flow controllers</h4><p>My flow controllers usually consist of more than one controller. Personally, I tend to “default” into making them a <strong>FamilyViewController</strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5054ceded48b4cd58216238ddb6bbfab/href">https://medium.com/media/5054ceded48b4cd58216238ddb6bbfab/href</a></iframe><h4>UICollectionViewCell</h4><p>This is not a very advanced template but seeing as I do all my UI components programmatically without interface builder, I always override the initializer and add my custom views there. This forces me to add the required initialize with coder function; the templates saves me the time it takes for the compiler to see that the method is missing and me having to invoke <strong>Fix all issues</strong>. It is not much, but everything counts in the long run.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/26cea47485c4393e0d8372ee7833a5f4/href">https://medium.com/media/26cea47485c4393e0d8372ee7833a5f4/href</a></iframe><h4>UIViewController</h4><p>This template simply implements the <strong>viewDidLoad</strong> method as this is where I tend to add the most of the setup for my view controllers and initializers are hard to make generic, especially if you rely on dependency injection.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/0c7ad1be2f58b434fff797178c260a3e/href">https://medium.com/media/0c7ad1be2f58b434fff797178c260a3e/href</a></iframe><p>As you can see from all my examples, my templates are very lean, some of them do little to nothing except taking the <strong>___FILEBASENAME___</strong> and use it as the class name. The reason for this is that I want them to be neat and tidy. I feel that if I make templates and need to remove a lot of things from them each time I’m about to use them, then they don’t serve their intended purpose. Too advanced templates are also more demanding to work with from a creative point of view, as it will require you to make decisions &amp; think things through before creating your canvas, sometimes without a relevant context. I like my canvas to be free of clutter which makes them more inviting.</p><p>When you start using templates, you’ll quickly find that it can be quite challenging to find a good middle-ground between what is semi-niche and what is perfectly generic. But remember, there are no right and wrong with templates, they should be personal, create templates that fit your needs and make sense in your context. If they don’t work out, just change them until they do.</p><p>If you have any good tips that you’d like to share, just hit me up on Twitter and we can compare notes. You can reach me at <a href="http://twitter.com/zenangst">@zenangst</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=98a08bf20038" width="1" height="1" alt=""><hr><p><a href="https://medium.com/itch-design-no/creating-your-own-templates-in-xcode-98a08bf20038">Creating your own templates in Xcode</a> was originally published in <a href="https://medium.com/itch-design-no">itch design</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to rotate tvOS into portrait mode]]></title>
            <link>https://medium.com/itch-design-no/how-to-rotate-tvos-into-portrait-mode-deff37cd56c8?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/deff37cd56c8</guid>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[tvos]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Fri, 20 Apr 2018 10:35:43 GMT</pubDate>
            <atom:updated>2018-04-20T10:35:43.247Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZWH0sPJw2HQ0HXRqVqEA4g.png" /><figcaption>Wang Xi — <a href="https://unsplash.com/photos/e676-HByCH4">https://unsplash.com/photos/e676-HByCH4</a></figcaption></figure><p>Continuing with some more niche topics, let’s have a look at how we could rotate your tvOS application to work in portrait mode. So what is “portrait” in tvOS, well… the concept from an SDK perspective does not exist. None of the rotation-related methods from iOS made it over to tvOS, and for a good reason. With that said, there is still a small segment where it could be useful to have your tvOS application being rendered with more vertical than horizontal space. A good example of this is Panic’s <a href="https://panic.com/blog/panic-status-board-2013-edition/">status board application</a> that was built back in 2013 using an iPad that would preferably be mounted on the back of the TV it was attached to. You could, of course, go with this option as well, but for our use case and this article’s topic, we will stick to using tvOS as the platform.</p><p>Before we tried to tackle this problem, we thought long and hard about how we could do this and still keep the application maintainable in the future. The first fear that stirred up was that this would affect how we write constraints, having to translate the layout in your head before writing it down in code. This felt like an unbearable scenario, so unbearable that we almost decided to ditch the idea of portrait entirely. After a small brainstorming idea on how to best tackle this, we came up with the idea to go down to the lowest (or highest) point in the hierarchy, more specifically the application’s window.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/fedc4cc285f116d7e43e7768074949f1/href">https://medium.com/media/fedc4cc285f116d7e43e7768074949f1/href</a></iframe><p>If we swap width and height, we end up with the correct frame measurements. However, the window was now misplaced. This is where our good friend transform made an entrance and saved the day.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c6f34ff85f05c7dc5f2a4645c9b9a3b7/href">https://medium.com/media/c6f34ff85f05c7dc5f2a4645c9b9a3b7/href</a></iframe><p>The first thing that we did was to get the rotation right, for our use case, we had to rotate the screen -270 degrees. This was easily done with a <strong>CGAffineTransform</strong>. And voila, now we had the correct screen rotation. However, the screen was now somewhat misplaced.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/ae67aaf53b9bc1e98f3bc674812b9d78/href">https://medium.com/media/ae67aaf53b9bc1e98f3bc674812b9d78/href</a></iframe><p>To fix the position, we needed yet another transform to be applied to the window, this time a translation of the <strong>x </strong>and <strong>y </strong>coordinates. These values are easily calculated, simply take the width minus the height and divide it by two, do the same for the y-position but negate the value. We then create the translation and apply it to our already existing rotation transformation by calling <strong>.concatenating</strong>. Using this method we can combine the two transform into one and finally apply it to the window.</p><p>And there you have it; the application’s window now uses a portrait window size, it has been rotated and positioned to fit in the middle of your TV screen.<br>The kicker is that you can now use the same kind of constraints that you would normally apply to your views without having to think about the screen rotating. Except for one small detail that I’d like to highlight when it comes to over-scanning.</p><p>In the tvOS human interface guidelines, Apple mentions that should have used at least 60 for your top and bottom insets and 90 for your left and right insets. Now that you have rotated your TV screen, you should reverse these values to be on the safe-side when dealing with over-scanning. So 90 in top and bottom and 60 on for the left and right insets.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=deff37cd56c8" width="1" height="1" alt=""><hr><p><a href="https://medium.com/itch-design-no/how-to-rotate-tvos-into-portrait-mode-deff37cd56c8">How to rotate tvOS into portrait mode</a> was originally published in <a href="https://medium.com/itch-design-no">itch design</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to generate QR codes in iOS]]></title>
            <link>https://medium.com/itch-design-no/how-to-generate-qr-codes-in-ios-f24d49da6400?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/f24d49da6400</guid>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[qr-code]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Fri, 20 Apr 2018 06:28:47 GMT</pubDate>
            <atom:updated>2018-04-20T06:28:47.062Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9p-pisGPV9cCxgJHIRPZzw.jpeg" /><figcaption>Willian Justen de Vasconcellos — <a href="https://unsplash.com/photos/0yQPd95ScSc">https://unsplash.com/photos/0yQPd95ScSc</a></figcaption></figure><p>Generating QR codes might be a niché subject, but it can be nice to know how to generate QR codes on the phone rather than just scanning them using the phone’s camera, and generating them is surprisingly easy. Let’s have a look at a straightforward example where we create our QR code based on a string, and as a bonus, we will put some customization to it by splashing some colors to it.</p><p>First, of, let’s create our subclass of UIView so that we gain the ability to easily place our QR code where we want in the application.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/62c0297465693e0345661c1d3d333bbe/href">https://medium.com/media/62c0297465693e0345661c1d3d333bbe/href</a></iframe><p>The next thing that we need to do is to add a filter, more specifically a CIQRCodeGenerator CIFilter. This specific filter has been around since iOS 7.0, so it’s is not particularly new. For more information about available CI generator filters, you can head over to <a href="https://developer.apple.com/library/content/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/uid/TP30000136-SW142">https://developer.apple.com/library/content/documentation/GraphicsImaging/Reference/CoreImageFilterReference/index.html#//apple_ref/doc/uid/TP30000136-SW142</a></p><h3>The CIQRCodeGenerator filter</h3><p>This particular filter takes two arguments:</p><p><strong>inputMessage:</strong> The data to be encoded as a QR code. An <strong>NSData</strong> object whose display name is Message.</p><p><strong>inputCorrectionLevel:</strong> A single letter specifying the error correction format. An <strong>NSString</strong> object whose display name is <strong>CorrectionLevel</strong>. Default value: <strong>M</strong></p><p>Because the correction level is optional, we will stick with the default value of that key.</p><p>However, we need a public method on our class to set an input message to the generator. Let’s add the missing pieces and see where we end up.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/def65e138ad10ec80e14e8773c95a4e4/href">https://medium.com/media/def65e138ad10ec80e14e8773c95a4e4/href</a></iframe><p>The first thing you’ll probably notice is that we have added an image view to our QR code implementation. The reason is that we get a generated QR code as a <strong>CIImage</strong> and we need a place to show it on screen. We do the usual limbo to add the image view to the view hierarchy and set a frame to it.</p><p>As for the <strong>generateCode</strong> method, it takes a string, but internally, one of the first thing that it does is to transform the input string into data. This is then used as the input message for our QR code filter. We supply the data and expect a <strong>CIImage</strong> as the output of the filter. This is accessed using the <strong>.outputImage</strong> property on the filter. We take the value and create a new image and assign it to our image view that was mentioned earlier.</p><p>If you run this code in a playground, you’ll notice that the QR code in question is a bit blurry, so let’s fix that plus splash some color.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/e310044186e373cc8af19171cda31157/href">https://medium.com/media/e310044186e373cc8af19171cda31157/href</a></iframe><p>If you take this and add it to a playground, you’ll end up with something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*p8W0K2SitXHqTej5ulT2Aw.png" /><figcaption>Try scanning this with your phone.</figcaption></figure><p>So here is what we did to achieve this result. To correct the issue with the image being blurry, we applied a transform filter and up the scale by ten. This is probably something that you’d like to tinker with to not sacrifice any performance, using a scale of ten is random to illustrate how the method works.</p><p>To set the color values that we want, we need to invert the colors and later mask the image so that the background becomes transparent.</p><p>For inverting, we use another <strong>CIFilter</strong> named <strong>CIColorInvert</strong>. This simply inverts the colors that were generated by the <strong>CIQRCodeGenerator</strong>, which are black and white. The input for that filter is the transformed image, and we use the key <strong>kCIInputImageKey</strong>, you’ll see this key being used when doing masking as well.</p><p>Now that we have an inverted image, it is time to apply a mask. For masking, we use a filter named <strong>CIMaskToAlpha</strong>. Just like the invert filter, it also takes an image as its input using the same key, <strong>kCIInputImageKey</strong>.</p><p>We are now done with a filter; it is time to put the pieces into place.<br>First, we set a tint color to our image view, this will be the color of the actual code. We proceed to set a background color to the actual image view; this will act as the background color for the code as we applied an alpha filter to our image.</p><p>Last put not least, it is time to set the generated image to the image view. Because we are working with the Core Image framework, we don’t have a UIImage yet. Lucky for us, UIImage as an initializer that takes a CIImage. The icing on the cake is when you set your UIImage to your UIImageView, you do that by adding .withRenderingMode(.alwaysTemplate). This last step is important as it will make the image adopt the tint color of the image view.</p><p>And there you have it; now you can generate your QR codes and personalize them by dashing your color schemes on them.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f24d49da6400" width="1" height="1" alt=""><hr><p><a href="https://medium.com/itch-design-no/how-to-generate-qr-codes-in-ios-f24d49da6400">How to generate QR codes in iOS</a> was originally published in <a href="https://medium.com/itch-design-no">itch design</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[UIProgressView performance on tvOS]]></title>
            <link>https://medium.com/@zenangst/uiprogressview-performance-on-tvos-dbb0ada3d2df?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/dbb0ada3d2df</guid>
            <category><![CDATA[tvos]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[application-performance]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Sat, 07 Apr 2018 10:46:53 GMT</pubDate>
            <atom:updated>2018-04-07T10:46:53.004Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WiRlXIt-NW3FBiXf2RDXDg.jpeg" /><figcaption><a href="https://unsplash.com/@jenskreuter">Jens Kreuter</a> — <a href="https://unsplash.com/photos/ngMtsE5r9eI">https://unsplash.com/photos/ngMtsE5r9eI</a></figcaption></figure><p>For the last couple of months, I’ve had the pleasure of working on a tvOS application. Developing for tvOS is very similar iOS which made it quite smooth to work with from the get-go. After multiple iterations on one of the features, we stumbled on some performance hits with one of our collection views. Spending time in Instruments revealed a lot of potential optimizations that we could apply, they included layout attributes caching for our collection views, further optimizations to our scrolling algorithm, etc. All optimizations rendered fantastic results for everything except one collection view that just did not want to perform well. Everything performed a stunning 60 fps except for that one collection view. This quickly became a thorn in my paw, and I set out on a mission to figure out why this was happening.</p><p>I lost count on the number of times I clicked on the Profile button in Xcode. I started to strip away UI elements, dove deeper into the profile stack, and I finally had a suspect in my crime noir tale of optimizing for tvOS. All evidence pointed to <strong>UIProgressView</strong> being the culprit. Now that we finally had found is big baddy it was time to figure out how to solve the issue. But before we jump into the solution, I’d like to present a theory of mine to why this was happening. Because I don’t know the inner workings of UIProgressView, I cannot present my theory as facts, but if you follow along, I think you would agree that it makes sense.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z7BjHQ_Er6GKmU2EOy2eBQ.png" /></figure><p>I first perceived this as a bug on Apple’s part and was going to file a radar, but after some more thought, this is more a cost of the implementation that Apple provides which makes it a bad fit for us to use in this context. With that said, we did not see the same kind of frame drops on new Apple TV’s which means that this issue will fix itself over time. We couldn’t just sit around and wait for our users to upgrade their hardware so hence we went with rolling out our own solution that would be more tailored to our needs and scaled in the way that we want.</p><p>Because the <strong>UIProgressView</strong> is designed to work in as many situations as possible, Apple went with <strong>UIVisualEffectView</strong>. I understand this choice; unfortunately for us, as mentioned above, this didn’t scale well as we were showing ten to eleven views at once which all used this implementation. It gave us a frame drop of 20 fps or more, depending on the device. Also, our design didn’t have to rely on <strong>UIVisualEffectView</strong> as we added a gradient to ensure that the progress view would always be visible to the user. You could say that the vanilla implementation that Apple provides was over-engineered for our use case. There could be other reasons for it not performing well for us, the solution that we used to solve the issue was to make our own version of the progress view that was not backed by <strong>UIVisualEffectView</strong>.</p><p>Because we wanted this to be a drop-in replacement for <strong>UIProgressView</strong>, the public API was copied from <strong>UIProgressView</strong>. It made it easier to start using the view as we only had to change which class to use instead of updating all the method calls made to the class.</p><p>Our replacement consisted of two <strong>CALayer</strong>’s, one outer layer that represents the total progress amount and another inner layer that represented the current progress. The outer layer has a corner radius that is equal to half of the height of the progress view; this gives it the same shape as you would expect from a <strong>UIProgressView</strong>. For animations, we provide a <strong>CABasicAnimation</strong> when we call <strong>setProgress(_ progress: Float, animated: Bool = false)</strong> that is added to the inner layer.</p><p>The layer and the animation are wrapped up in a regular <strong>UIView</strong> to make it easier to work with as <strong>CALayer</strong>’s lack the ability to use constraints.</p><p>After dropping in this new progress view into our app, our application started reaching 60 fps again, and the users got the performance that they so truly deserve.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dbb0ada3d2df" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Converting frames between view coordinate systems]]></title>
            <link>https://medium.com/hyperoslo/converting-frames-between-view-coordinate-systems-46af928ba6c0?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/46af928ba6c0</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[macos]]></category>
            <category><![CDATA[app-development]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Tue, 06 Mar 2018 11:34:41 GMT</pubDate>
            <atom:updated>2018-05-24T05:29:40.243Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Ln5fiKHwHK2XBR_58djPDw.jpeg" /><figcaption><a href="https://unsplash.com/@iswanto">Iswanto Arif</a> — <a href="https://unsplash.com/photos/OJ74pFtrYi0">https://unsplash.com/photos/OJ74pFtrYi0</a></figcaption></figure><p>Knowing the exact position of a subview is a technique that can come in handy on multiple occasions. You might want to know if the view is visible to the user, perform an animation from the views initial position or restore the view to its original destination. There are plenty of use cases for this; you can probably think of dozens more. However, when you want to do this you can’t simply rely on the target view’s frame as that is only a part of its super-views coordinate system, this quickly causes issues depending on how you compose your view hierarchy. Lucky for us, both <strong>UIView</strong> and <strong>NSView</strong> have some methods to give us the desired results. If you read a previous article of mine about how frames work on macOS, you might remember that we briefly touched on coordinate systems.</p><p>So let’s dive in to see how we can convert frames between different coordinate systems.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/4c6bafb61c2351d81e7e8722546789e9/href">https://medium.com/media/4c6bafb61c2351d81e7e8722546789e9/href</a></iframe><p>The first thing that we create is a <strong>UIWindow</strong>. We give it a frame and later assign a root view to our newly created window. We give the root view a color so that we can more easily see where on view start and the other one begins.</p><p>Next is your view, this is meant to represent your custom view implementation. It gets a frame and a color and is added as a subview on the window. So far we have only written code to get the example up and running, nothing new and exciting.</p><p>Last but not least is the subview, it gets the same treatment as the other ones and is added as a subview to the view.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/300/1*vYjgebIcg-BsiLYLrj0NTA.png" /></figure><p>Now that we have our scenario set up let’s look at the method that the whole article is about, the <strong>convert(CGRect, to: UIView?)</strong> method.</p><p>If we examine the values that we get back from just accessing the view’s frame. It is the correct value inside the views coordinates space, but that doesn’t make it universally correct when trying to assemble these kinds of values in a context that expands to the outside of the views coordinate space.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/526/1*mrRnw-6hJi-R81CJiO1wuQ.png" /><figcaption>The view frame without converting.</figcaption></figure><p>What we want to achieve is to know the views exact position on the screen, not the position within the subview.</p><p>So by passing the current frame and pointing it to the desired coordinate space, we can now get the measurements that we need. You can switch to any coordinate system that you like; I picked the window as that has been the most relevant for me in the past.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/470/1*JVJDaQetehToDi-CSLNSjQ.png" /><figcaption>The view frame converted to the windows coordinate system.</figcaption></figure><p>When doing this in your implementation, accessing the view’s window is trivial. All <strong>UIView</strong>’s has an optional reference to the window it belongs to, if this value is nil it means that the view hasn’t been added to a window yet.</p><p>As a side note, this is just the tip of the iceberg; there are more of these kinds of methods that take points instead of a frame. Have a look at <strong>UICoordinateSpace</strong> for more information.</p><p><a href="https://developer.apple.com/documentation/uikit/uicoordinatespace">https://developer.apple.com/documentation/uikit/uicoordinatespace</a></p><p>The reason why these methods are also available on <strong>UIWindow</strong> is that it inherits from <strong>UIView</strong> which in turn conforms to <strong>UICoordinateSpace</strong>.</p><p>As you can see, this is straight-forward yet powerful, but what about macOS. Let’s have a look at another example with some macOS code.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/677ceaa211fa114d41d1303f3031ea5e/href">https://medium.com/media/677ceaa211fa114d41d1303f3031ea5e/href</a></iframe><p>The technique itself remains the same, as well as the result when converting. The only noticeable difference between the two examples is that it uses an <strong>NSView</strong> to represent the window. The reason for this is that <strong>NSWindow</strong> does not conform to <strong>PlaygroundLiveViewable</strong>.</p><p>Even if this might seem niché, this technique holds enormous value when reasoning about how to solve specific situations. I’ve used this method when optimizing scrolling performance of both scroll views and collection views, opting out from performing layout operations if the view is not visible on the screen. I’ve also used these kinds of values to define start and end positions for core animations. I’m sure that you can come up with more scenarios, the point is that knowing the technique expands your toolbox and the bigger toolbox that you acquired, the more natural is to find the best solution for your problem.</p><p>Hope you found this useful, for me, this has been life-saver countless times.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=46af928ba6c0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hyperoslo/converting-frames-between-view-coordinate-systems-46af928ba6c0">Converting frames between view coordinate systems</a> was originally published in <a href="https://medium.com/hyperoslo">hyperoslo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Seeking out inspiration]]></title>
            <link>https://medium.com/hyperoslo/seeking-out-inspiration-1a671ed23c3f?source=rss-b7d8a2928bfc------2</link>
            <guid isPermaLink="false">https://medium.com/p/1a671ed23c3f</guid>
            <category><![CDATA[inspiration]]></category>
            <category><![CDATA[life-lessons]]></category>
            <dc:creator><![CDATA[Christoffer Winterkvist]]></dc:creator>
            <pubDate>Sat, 03 Mar 2018 15:54:30 GMT</pubDate>
            <atom:updated>2018-03-03T15:54:30.074Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Avhwvk5GaII6pLr48VCbIg.jpeg" /><figcaption><a href="https://unsplash.com/@anastasia_p">Anastasia Petrova</a> — <a href="https://unsplash.com/photos/xu2WYJek5AI">https://unsplash.com/photos/xu2WYJek5AI</a></figcaption></figure><p>For the past months I’ve been feeling a bit down, well that is probably the wrong word for it, uninspired is probably the right word. It isn’t a crisis of faith or anything like that, but I’ve been feeling that something has been lacking. Days became weeks and I realized that this problem wouldn’t fix itself. I got tired or waiting, so I had take action. If inspiration wasn’t going to find me, I was going to find it.</p><p>The plan of attack was to get exposed to new things. The conditions for this to work was that it had to be contextual to my profession, feel natural and last but not least, it should be fun. So this is what I came up with.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/489/1*wnJrGAfvnBwq1DKoljo6YQ.png" /><figcaption>Yeah, I use emoticons for my reminder lists, don’t judge me!</figcaption></figure><p>To get things off the ground, I simply set up a bunch of reminders for myself and made the tasks obligatory. Those far I have three semi-concrete action points that I want to do on a regular basis. Seeing that humans are creatures of habit, doing something repeatedly will eventually make it second nature. So the first thing on my list was, read an article. The subject doesn’t matter but read something, anything. I prefer Medium as my source of articles these days; I like the aesthetic of it, and they could be written by anyone from any field, writing about anything.</p><p>The second thing on my list is, check out new open source. The code doesn’t have to be new, but it has to be new to me. There are a thousand ways to skin a cat, looking at how other people solve similar problems that you face on a regular basis can be inspiring and fun. Knowing that there are more options than you can come up with yourself is never a bad thing.</p><p>The last thing on my list was to write something. As long as I can remember I’ve always enjoyed the art of writing, if it’s sharing a personal experience, giving someone praise or explaining the internals of a piece of code I just wrote. I see writing as an outlet for my thoughts, and if I don’t let them out, I start to feel “thick-headed,” and no one wants to feel like a hard drive with little disk space.</p><p>To conclude, the way I see it, my problem with not being inspired boils down to me waiting for it to happen rather than actively seeking it out. If you feel that your personal or professional life is lacking or you’re just feeling uninspired, try doing something about it. It might be easier than you think.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1a671ed23c3f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/hyperoslo/seeking-out-inspiration-1a671ed23c3f">Seeking out inspiration</a> was originally published in <a href="https://medium.com/hyperoslo">hyperoslo</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>