Weekly Swift 1, warming-up

It's been my goal to learn how to build apps for a bunch of years now. I’ve picked up some books on Objective-C, tried building some things but lost interest really quick every time. The first time I actually went through with building something was when I was graduating from college. Shortly after that Swift came out and I wanted to learn it. But, once again, with no real goal except just learning Swift I quickly lost motivation to actually do something with it.

But then something happened, I realized that motivation is fleeting. It’s not reliable, one day I could be super motivated and the next day I was too tired to care. So I set out to become more disciplined. And part of this would be learning Swift. I decided to start something called Daily Swift. The idea is to build a (sometimes very) small and simple project in Swift. I have decided to not use Storyboards / Interface Builder because I feel like most pros out there prefer not using it. The projects I build should usually be very bare bones and exactly what I’m missing in Swift resources.

A lot of resources on Swift that I have found are either too complex, or they rely on Interface Builder to work. I feel like the things I’m going to push out are a lot more simple and don’t rely on Interface Builder. If you're like me, a developer who is struggling with these storyboards and overly complicated examples you might want to follow along. And, more importantly you might have some feedback for me or have a subject you'd like me to look into. Please let me know on Twitter.

In my first week I’ve noticed that there’s really tons of magic in Apple’s UIKit framework. They have pretty good documentation for it but sometimes I did have to really force myself to read it all. When you just glance over everything you will surely miss a very important detail and nothing will work and there will be errors all over the place. Also, the use of ? and ! is just confusing in Swift. The ? tells the compiler that something is either an instance of a class or nil. And the ! seems to promise the compiler that you know what you’re doing and the variable (or constant) you’re using is not nil. When I have a better mental model of this I will write about it.

Also, I’m amazed with how much you can learn about Swift in just a single week. I’ve learned how to use Alerts and Actionsheets. I learned about TableViews, TabBars and NavigationControllers. And more interesting, I learned how to add images from an online resource to a TableView without blocking the main thread. (Blocking the main thread by just grabbing the images would make for very choppy scrolling.) And even more interestingly I learned how to load images with HanekeSwift thanks to a tip from @mwildeboer.

My goal for now is to be able to build a Swift version of Arto App. I built this app as an assignment during my minor and I've always imagined it as an iOS app. All the JSON APIs are there already so I’ll be using them as input for some examples and eventually I will bundle them together into a project that would be the iOS version for Arto.

Thanks for reading and if you want to follow my journey you can do so on Twitter and Github.

Expand your learning with my books

Practical Swift Concurrency (the video course) header image

Learn everything you need to know about Swift Concurrency and how you can use it in your projects with Practical Swift Concurrency the video course. It contains:

  • About ten hours worth of videos and exercises
  • Sample projects that use the code shown in the videos.
  • FREE access to the Practical Swift Concurrency book
  • Free updates for future iOS and Swift versions.

The course is available on Teachable for just $89

Enroll now

Avoid thinking in pixels

When writing CSS for websites it's easy to use pixels for everything. Just measure up everything in the design you were given, fill out the numbers and you're done. You've built a beautiful pixel perfect website. Until somebody comes along with a mobile phone. Or their 13" laptop. Or maybe somebody is using a fancy 27" iMac screen. The retina version I mean. Then everything looks weird. Maybe the design doesn't quite fit, causing a vertical scroll. Or maybe the design is an old fashioned 960px grid site. That would certainly create huge amounts of whitespace. Oh and then there was that retina display. Everything looks a bit blurry there.

The point I'm trying to argue here is that pixels are old fashioned. Technically a pixel is a single RGB light that can light up together with many other lights to create an image on the screen. So when you imagine a retina display the pixels are actually smaller. So 1px on a normal screen is four(!) times larger than one on a retina display. I've argued with designers over this. A lot. They view a pixel as this absolute unit of design. Double the pixel density, you double the size of your design. And then you make your design. Font size 16px because that looks great. Except.. you doubled the size of your entire design. So the font sizes should double as well. And you should zoom out twice, because that's how everything will look on your user's screen. Probably. Because you have no clue about the actual pixel density. So, how in the hell are you supposed to solve this?

Well, the solution is simple and extremely complicated at the same time. Drop pixels. Just try to not think in terms of something being 300px wide. Think of it as 25% of the screen width. And then when you resize your browser and the layout becomes cramped, come up with a new percentage. Maybe something like 50%. And then when the screen is even smaller you might want to scale up to 100% width, allowing all columns to line up vertically so a user with a small screen can scroll down to view content. This obviously poses a few usability problems that I'll not go in to right now. Just make sure that content can be navigated properly with a good menu for example. Okay, I'm drifting off. Let's get back to this dropping pixels thing.

When you start defining widths as percentages for your layout you suddenly are extremely flexible. Maybe even a little responsive! Or fluid.. Or both. When you combine these percentages with good breakpoints (base these on your content, not assumptions about devices. Your assumptions are probably wrong.) you get a good responsive layout.

Another nice practice is to start working with (r)ems. The em is a unit relative to the font-size of the containing element. So if you have a section, and you give it a width and height of 10em you essentially give this element a size of 160x160px. This assumes that your user didn't change their browser defaults. Now imagine that you have a list of four items, one should be highlighted. If you've defined the styling for your item in ems, you could highlight one by simply increasing it's font size.

One last thing to mention is how you would go about converting that pixel design you were given to css without pixels. Well, you could start by calculating everything in percentages by taking the design width and the width of the component your styling. Divide the component width by the design width, multiply by 100 and there's the percentage width. To get a size in em divide a size by the font-size (960px /16 = 60em).

This might all seem (over)complicated. And honestly, it sometimes is. And when you nest a few levels and then change the font-size everything gets even more complicated. But I feel like it's all worth it. As soon as you start viewing your content on different devices and see how easy everything just flows into the correct places with almost no extra code, you feel like you're totally on top of the world. Oh and you get bonuspoints for doing that mobile first. Adding things, making them larger and displaying more content is always easier than making things smaller, hiding things (hiding rarely is a good idea) and complicating interactions.

So, yeah, my two cents on a design topic. Something I'll probably be writing more about in the future since my new job requires me to write a whole lot of front-end code.

Sharing cookies between subdomains

A while ago I wrote about sharing cookies on an old Tumblr blog of mine. I figured it contains some valuable information so I migrated the post here. The reason I wrote it was that I was working on a pitch that would take a user through a series of puzzles. Each puzzle would enable the user to see the next website(subdomain) and I decided I'd save the progress of the user in a cookie.

Normally you'd define a cookie for a domain like www.example.com. When the browser tries to read this cookie, the current domain has to be www.example.com. So sub.example.com wouldn't work and the cookie won't be read. There is, however, a way to get around this security limitation and it's quite easy.

If you only specify .example.com(note the period before example.com) as the host for your cookie, it will be accessible for every subdomain from this host. So both www.example.com and sub.example.com can use this cookie.

An example in code (using the jquery cookie plugin):

$.cookie('foo', 'bar', {path: '/', domain: '.example.com'});

Well, hope it's helpful to some of you out there.

Using Angular UI Bootstrap modals

While working on a personal project I figured I'd use Bootstrap because then I wouldn't have to worry about styling. All was very well and using Angular.js together with Twitter Bootstrap totally made my day. But then I needed to show a modal dialog. I know how to do this but I stumbled upon the Angular UI directives for Bootstrap this seemed great. I mean, that's just awesome. Using the power of Angular's directives should get these modals up and running super fast. Or so I thought..

After skimming the docs and looking at the modal example I figured I'd give it a go. I set up my templates and wrote some code. Clicked on my button and then.. nothing. Just some error message.. My code looked like this, and from the docs I understood that this would be fine.

(function(){
    var app = angular.module('cmsRecipesModule', ['ui.bootstrap']);
    app.controller('cmsRecipesController', [
        '$scope',
        '$rootScope',
        'recipeService',
        '$modal',
        function($scope, $rootScope, recipeService, $modal){
            $scope.recipes = recipeService.recipes;

            $scope.deleteRecipe = function(id) {
                $modal.open({
                    templateUrl: '/templates/modal.html',
                    controller: 'ModalCtrl'
                });
            }
        }
    ]);

    app.controller('ModalCtrl', [
        '$scope',
        '$modalInstance',
        function($scope, $modalInstance){
            console.log('instance');
        }]);
})();
<div class="modal-header">
    <h3 class="modal-title">Weet je zeker dat je dit recept wilt verwijderen?</h3>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
    <button class="btn btn-primary" ng-click="ok()">OK</button>
    <button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>

This was just like the docs told me to do it and should've worked just fine. But it didn't, my code wouldn't find the window and backdrop templates. So I added the template folder from angular-ui to my project but that led to another error telling me my template needed one root. And one root only. This bugged me, I did the same things with my template as the examples did and they worked fine. So then I turned to some more searching online an I found this Github issue. This person was having the same issues I had and the solution was simple. He made a 'beginners mistake' because he forgot to list ui.bootstrap.tpls as dependency for the module that was creating the modal window. After I added this dependency everything was working just fine. So, to everybody getting an error about their templateRoot when trying to use the modals from angular ui's bootstrap directives. Make sure you added ui.bootstrap.tpls.

My final code for the controller ended up like this:

(function(){
    var app = angular.module('cmsRecipesModule', ['ui.bootstrap', 'ui.bootstrap.tpls']);
    app.controller('cmsRecipesController', [
        '$scope',
        '$rootScope',
        'recipeService',
        '$modal',
        function($scope, $rootScope, recipeService, $modal){
            $scope.recipes = recipeService.recipes;

            $scope.deleteRecipe = function(id) {
                $modal.open({
                    templateUrl: '/templates/modal.html',
                    controller: 'ModalCtrl'
                });
            }
        }
    ]);

    app.controller('ModalCtrl', [
        '$scope',
        '$modalInstance',
        function($scope, $modalInstance){
            console.log('instance');
        }]);
})();

Creating a multi step form with Angular.js

Before we start, you might want to check out this example of the form in action.

While I was working with Angular.js to create a nice little recipe / cookbook site for myself, I was creating a form that required me to split it up into multiple parts or steps. I found this surprisingly easy to do actually but I can imagine that not everybody will have the same experience I did. In this short post I will provide you with a good starting point for your html and your javascript.

I'll be using the power of Angular.js directives to hide and show parts of the form. Well, let's dive in then!

First of all, we'll set up a form. It could look a little like this. I'm using bootstrap to style the form in this example. You can just ignore the classes I've used.

<form class="form-vertical" name="myForm" ng-controller="FormController" novalidate>
    <fieldset ng-show="step == 1">
        <legend>Step one</legend>
        <div class="form-group">
           <label for="name">Your name</label>
           <input class="form-control" type="text" id="name" name="name" ng-model="name" />
        </div>
        <button class="btn btn-primary" ng-click="nextStep()">Next step</button>
    </fieldset>
    <fieldset ng-show="step == 2">
        <legend>Step two</legend>
        <div class="form-group">
            <label for="email">Your email</label>
            <input class="form-control" type="email" id="email" name="email" ng-model="email" />
        </div>
        <button class="btn btn-default" ng-click="prevStep()">Previous step</button>
        <button class="btn btn-primary" ng-click="nextStep()">Next step</button>
    </fieldset>
    <fieldset ng-show="step == 3">
        <legend>Step three</legend>
        <div class="form-group">
            <label for="msg">Short message</label>
            <input class="form-control" type="text" id="msg" name="msg" ng-model="msg" />
        </div>
        <button class="btn btn-default" ng-click="prevStep()">Previous step</button>
        <button class="btn btn-primary" ng-click="submitForm()">Submit</button>
    </fieldset>
</form>

So, that's not very bizarre right? It's a regular Angular.js style form with a bunch of fieldsets. The magic happens with the ng-show directives that are set on the fieldsets. These directive will make sure that we will only show a certain fieldset if the step property of our controller is equal to a certain number.

Let's tie this up with some Javascript.

(function(){
    var app = angular.module('myApp', []);
    app.controller('FormController', ['$scope', function($scope){
        $scope.step = 1;

        $scope.nextStep = function() {
            $scope.step++;
        }

        $scope.prevStep = function() {
            $scope.step--;
        }

        $scope.submitForm = function() {
            // submit code goes here
        }
    }]);
})();

If we were to test this out in an actual app we would have a pretty neat form that spans multiple steps. The model data is preserved for each because we're just showing and hiding different parts of a single form!

Source on github