Understanding $PATH

Open your terminal and type in

echo $PATH

and you’ll see an output that might look something like

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

Each of those paths (separated by a colon) points to a directory that contains executables. All of those directory locations are part of the user PATH file- a grouping of places where executables can be kept. If a file called “node” is contained in one of those folders, typing “node” into the terminal will immediately look in the user path folders for a file called “node” - this itself might be an executable or might be a symbolic link to an executable located elsewhere. Either way, the ability to just type a single command and execute a program is due to the PATH file.

The PATH file itself is just a list of directories that tell the kernel where to look for the executable. There is an order in which the paths are checked for that executable - it’s the same order that the paths are printed to the console.

If you use ls -l to list all of the contents of one of the PATH directories, you’ll see some interesting stuff.

Anything prefixed with an “l” on the left side of the output is a symlink to an executable. There are probably files int here that are just a word as the filename - no extension, no path associated with it. These are pure scripts. If you open any of these pure scripts up, you’ll see a shebang at the top of the script. The shebang is the next thing we’ll cover here.

A shebang at the top of a script looks something like this - 

#!/usr/bin/env python

This line tells the kernel where to find the interpreter that will be used to interpret the lines of code contained in the rest of the script. It’s also possible to use 

#!/usr/bin/python

However, if this script is running on a different machine and the python executable isn’t found in /usr/bin/python, the script won’t run. “Env” is a script itself that acts much as the shell would - it will search the directories loaded in the PATH file until it finds the interpreter specified. Including the “env python” makes the script more portable.

If you use VS Code, there is a feature to add the executable path to the user PATH file with a single click - it simply adds a symlink called “code” to  one of the directories listed in the PATH file which leads to the actual executable file. To prove this, after adding the “code” command to the PATH file (using VS Code, not doing it manually), type in 

which code

in terminal to see the location of that command (which will be a directory that is listed in our PATH file). Open that folder and you’ll see an icon called “code” with an arrow pointing out - a symlink that leads to the VS Code IDE executable. That’s how we can now type “code” and launch our editor. 

To edit the PATH file and add a new directory path to it, we can type

$ export PATH=$PATH:/path/to/directory

Note that this is different from

$ export PATH=/path/to/directory:$PATH

The former will add the new directory to the bottom of the list so it will be checked last when searching for an executable - the latter will add the new directory to the beginning of the list so it’ll be checked first. *THIS WILL NOT PERSIST CHANGES TO THE PATH FILE*. In order to globally change the directories listed in the PATH file, the users ~./bash_profile or ~/.bashrc file must be edited directly.

This is all important to keep in mind when either scripting or building a CLI tool. More on that later.

Project Architecture

I’m going to go over a few of the points of my project architecture as it currently exists - this won’t include any token based authorization (which I’m in the process of adding). Click here to view my github repo and see the project as it currently exists.

index.js

The server is set up with the following files - index.js, handlers.js, data.js, config.js and helpers.js.

We begin by exporting the correct config object from our config.js based on the environment specified - the code defaults to staging unless PRODUCTION is specified as the process.env.NODE_ENV parameter when starting the survey. The config object contains some other properties to be discussed later - the important part for now is that based on production or staging environments, we have a specific port our server listens on.

Once a request comes in at the port we’re on (pre-deployment here), our server receives it and passes it along to a server logic function.

That function uses the Node.js URL module to parse the request object

  • It first grabs the pathname and trim it. We use this object later to check that our router has the specified path.

  • Next, it gets the query string (for GET requests, since our POST requests will be coming in the request body).

  • Next, it gets the HTTP request method (GET, POST, PUT, DELETE).

  • Finally, it gets the request headers (content-type, for example).

The same server logic function then handles collecting body data (for POST and PUT requests) using an event emitter (req.on). It currently uses a string decoder to append data to an empty string but this can likely be changed by preemptively specifying utf-8 encoding.

Once the request data has been collected, we implement our routing logic with a small router object. This is where the trimmed pathname comes in to play - if the path exists in our router object, we assign that to a handler variable. If it doesn’t exist, we deal with a “not found” scenario.

Our handler variable now contains a reference to a handler function name in our handlers.js file - we then create an object using the information gathered from the request object - this includes parsing our gathered data string to an object using a helper function from our helpers.js file.

Our handler variable (which is a function) calls the appropriate function in our handler.js file and passes along our data object (containing the information gathered from the client request) and will receive a status code and a payload from a callback.

data.js

Before we dive into the handlers.js file, we need to look at the data storage functions we have here. These are what ultimately get called by the handler functions once they extract the appropriate data from the client request data object sent from the index.js file.

It’s important to note that we have a folder within our project directory called “.data” - this is where we store our data. Additionally, that folder has subfolders such as “token” and “users” for specific pieces of data.

Our data object that we export from the data.js file has four functions - create, read, update and delete. These all correlate to handler functions that work with CRUD functionality. This project currently only write to local file stores (soon to be updated to use MongoDB or a hosted PostgreSQL DB - I haven’t decided on which) - as such, the first thing the data.js file does is grab the current project directory. We also create a .data file to store data files (one per user) and add that on to the project directory filepath so that we can write files to it.

The create function takes a directory, filename to create, data object and a callback (which returns an error and data - data in the event that we’re reading a file and need to return the contents). We open the file using the project direcotry, file directory and concatenating the filename and “.json” and pass the appropriate I/O flags - they allow for writing to the file and also create the file if it doesn’t exist. If there is no error, we have a file descriptor ready to use.

We take the date object to write (which is a javascript object), stringify it and call fs.write, passing along our file descriptor and the stringified data object. If there is no error, we close the file. We also handle all possible errors sent from callbacks along the way.

The read function accepts as parameters a directory, a filename and sends a callback to the handler that invokes it (responding with an error and the data we’re reading from the file system). The subfunction in the handlers.js file that calls the data.read function passes along a data object containing identifying data used to find the right file to read from (we’re using a phone number in this case). Just as with the create function, we use the node fs module to read the file using the project directory + file directory + filename passed + “.json” - if there is no error and there IS data from the callback, we parse the JSON to an object and include it in the callback.

The update function accepts the exact same parameters as the create function - we need to check that the file exists so we first open it. If it exists, we truncate the file using the file descriptor passed from opening it - if there is no error, we use fs.writeFile and stringify the data before passing it to the file. Then we close the file and we’re all done.

Our delete function takes the same parameters as our read function (since, at its core, it performs the same task of reading the file). We open the file using out project directory variable + directory + filename + “.json” - we pass that to fs.unlink and if there is no error, we callback “false” as an error.

handlers.js

Our entire file is a large exported function with subfunctions - this is similar to our data.js file. Our file has several objects - a handlers object (which is what we export) and a handlers.users object which houses all of our route handlers. This is somewhat encapsulation - files importing our handlers.js file only have access to the handlers object, not the handlers._users property of handlers (which itself is an object). We access handlers.users FROM the handlers object. To illustrate this point :

var handlers = {}
// our index.js router is going to hit this function here but has NO knowledge of handlers._users
handlers.users = function (data, callback) {
    var acceptedMethods = [‘get’, ‘post’, ‘put’, ‘delete’]
    var requestMethod = data.method.toLowerCase()
    if (acceptedMethods.indexOf(requestMethod) > -1) {
        handlers._users.requestMethod (data, callback)
    }  else { callback (405) 
    }
}
var handlers._users = {}
var handlers._users.post = function (data, callback) { // logic here…}
module.exports = handlers

Here’s what the handler object that is exported would look like as an object literal -

var handlers = {
    users : function (data, callback) { // put request method validation code here} , 
    _users: { 
                 post = function (data, callback) { // post route logic here } ,
                 get = function (data, callback) { // get route logic here } ,
         }
}

The users property of the handlers object is itself an object - however, that is abstracted away from our index.js file which only calls the handlers.users method (which in turn calls the requisite handlers._users method.

The post function is passed data and a callback method from our index.js file - we’ll return a status code and a payload object (an error, if we have one) back to the calling function in index.js. The data object, remember, has a querystring or a payload we collected using an event listener on the client request object.

It’s important to note that we’re going to consistently use an inputted phone number as our FILENAME - this will be used for all lookups. We have several required fields that must be present in our data payload in order to create a user - phone number, first name, last name, password and tosAgreement. We extract all of those values from data.payload - if we have successfully extracted ALL of them, we can continue. First we sanity check to see if the user exists - we call data.read and pass in the phone number as our filename and “users” as our file directory. IF THERE IS AN ERROR, THAT MEANS THE USER DOES NOT EXIST - we may proceed with creating the user.

First we need to hash our password - we create a hash function in our helpers.js file that hashes our user password. You can use an HMAC and store the hash key in the config.js file (add it to your .gitignore directory) or just use a SHA256 hash without a hash key. We sanity check the length and type of the object to be hashed and then return the hash. Back in our post function, within our call to data.read, if we were successfully returned a hashed password, we build an object to store on file. It contains the phone number, first name, last name, tosAgreement and the HASHED password - we then call data.create, pass in the users directory and the extracted phone number as the filename and pass in our object we created. We then handle all err first callback responses accordingly and we ourselves return 200 as the statusCode in our callback to the index.js handler function.

Our get function accepts data and a callback - as with all other handler functions, we’re going to call back a status code and a payload (which is an optional error object). We are looking for the query string here in the URL since we aren’t doing anything with data collection from the request object - we need to extract the phone number from data.query.phone. This SHOULD be the same as the filename in our .data/users folder so we can use that for lookup. If we successfully got the phone number from the query, we initiate a call to data.read and pass in the users directory and the phone number as the filename. If there is no error and there is data, we can remove the hashed password from the data object before returning it in a callback along with a 200 status code.

Our put function is a little bit more involved in terms of logic - we only want to overwrite fields that need to be changed. While we’re not going to compare new values to the original ones, we can always add in later. As it stands, if a user submitted a new first name as “Karan” and the first name on file is “Karan”, we’ll still replace it. A phone number is a required field here - we need it to read the file contents. If we managed to extract a phone number, we see if there is a first name, last name or password to update. If ANY of those fields have been sent in the request body, we need to change them. We call data.read and pass in our phone number as the filename - if there is no error and we ARE returned a data object, we replace the data objects property values with our new ones if they have been included in the request body. We then call data.update and pass along our new data object and proceed to handle all err first callback cases.

Our delete function is very straightforward - we take in data and return a callback as with all other handlers methods thus far. We check the data query for a phone number - if we manage to extract it, we read the user’s file to make sure they exist. If we can read the file, we then call data.delete and handle all err first callback cases.

That’s it so far! Follow up posts will include more writing and code samples for the next set of features to add in - token based authentication, building out a simple front end with vanilla Javascript and (probably) replacing all callbacks with async/await since it comes standard out of the box with the new V8 engine now.

Lessons Learned Building a Pure Node Project

This is an article I’ll be adding to as I (inevitably) come across more issues working with node.js - this is a list of problems encountered and the solutions that worked for me.

I’ve been building out an API for the last few weeks whenever I get a chance - it started as a CLI to check website responses (think isitdown) but I’m now going to build out a vanilla JS front end for it. The API is in pure node - no external dependencies, no package.json file, nothing but the local modules bundled with the node.js installation package.

This was originally a project meant to teach me more about node.js itself and general basic backend work. Little did I know how much I’d gain from working on this - working with pure node.js is pretty fun. The biggest downside I’ve experienced so far is callback hell - I wanted to work without promises or async/await and thus have had no choice but to deal with callbacks. Even in a file with as few as 150 LOC, it’s difficult at first glance to understand where each callback fits in with the program flow.

Besides my index.js file which creates an instance of an HTTP and HTTPS server, I have a few other typical files - a config.js file, a data.js file which contains my local file storage methods using the fs module, and most importantly, a handler.js file which is just a layer over the data.js functions and routes requests to the appropriate data.js function (with a little extra code in there).

The First Problem

One thing I spent far too much time on was an undefined object value in JavaScript - this could be due to a million different things, so combing through the source code was necessary. Was I performing an asynchronous operation somewhere (either setting or getting the object property/value pair) and accessing it before the operation completed? No. This was the most likely culprit to me, but it didn’t seem to be happening anywhere.

Essentially I was trying to access a configuration property value - it was my HMAC secret key. The config file had it right there in front of my face so I knew I wasn’t trying to access something that just didn’t exist. Additionally, and THIS was the confusing part - I could get the value of any other config object property. The only one that came back undefined every time was my secret key.

I was stumped. At some point I realized I was probably referencing the config file incorrectly (this was a shot in the dark). I found my answer - I had changed the directory structure of my project and had put the config.js file in a new spot. I had forgotten to change my require() statement at the top of my file referencing the config object to point to the new file location.

How was it possible that I was still able to reference PART of my original config object even though I wasn’t pointing my require statement to the correct location? Cache, cache, cache. I’ve been using VSCode and, according to what I’ve read, it makes heavy use of caching. It had cached the old file and was keeping it around in the editor - whatever changes I made to that file (adding in the HMAC key) were SHOWING that they were being made to the code, but they were saving to the NEW location that wasn’t actually being referenced.

Once I changed the require() statement, everything worked perfectly.

Weird Errors in JS

I was met today with two error messages when continuing to build my Node.js project - one I’d seen before, the other was new. Javascript, as a dynamically-typed and interpreted language, can display strange behavior that can be tricky to understand at times.

Today I received the following error when trying to log an object:

This is me recreating the issue using a null prototype object

This is me recreating the issue using a null prototype object

This happened when I tried to concatenate a string I was printing to the console with a URL query string object:

console.log('this was the URL query string contained in the client request:' + queryString)  

To try and pin down what was happening, since I knew I could make no assumptions about the queryString object being received since I didn’t create it, I created a mock queryString object:

var queryString = {‘foo’ : ‘bar’}
console.log('this was the URL query string contained in the client request:' + queryString)

This time, I managed to print it out without any issue (even though the object didn’t actually print out and instead showed [object Object]). That output is the correct string representation of an object that hasn’t been stringified - I realized that the javascript engine was using type coercion to convert my mock object into a string (since I was concatenating it to an actual string, it was treating the whole thing as one string). I figured the engine must have been calling toString() on that object - why wasn’t this happening to the ACTUAL query object I was getting from the client request?

I opened up Chrome and used the browser console there since it lists out type methods available that can be called on a given variable. I recreated my mock query string object and, using the dropdown, saw that toString() was available to be called on it. That showed me what was happening, more or less, in my node project - by concatenating to a string, the engine was coercing my object into a string by calling toString() on it, leaving the [object Object] string representation printed to the console.

Again in Chrome, I created a null prototype object with the same key value pair that I had in my original mock queryString object. When I used the dropdown to check the prototype methods available, there was no toString() to be seen - what I guessed was happening was that the prototype of the request URL query string object was inheriting from a prototype that didn’t have the toString() method available. As a result, when trying to coerce the object type to string, the engine possibly tried calling toString(), found that it couldn’t and printed the error to the console about being unable to convert to a primitive value.

The Solution

Instead of concatenating an object of unknown origins to some user printed string, just use a comma instead of a “+” operator! This has the additional bonus of not converting (or attempting to convert) the object to a string

The Next Error

The second error I came across was when I had a block of code that I realized executed two callbacks when dealing with the same request. “Error: Can't set headers after they are sent." was what I was shown on the terminal after my server crashed - I could figure out WHAT was happening from the error message but I wasn’t sure WHY it was happening.

NodeHeaderError.png

The error message itself can be a little confusing - what’s happening in this case is that a handler callback is sending a status request and payload to our index.js file. We send a response header when the first callback is returned - we’re then calling res.end(), closing the process. A little bit further down in our handler function, we’re trying to send ANOTHER callback to the same request (even though the process has ended), resulting in our error.

The Solution

Use log statements or your preferred debugging method to figure out which function is causing the issue - once you’ve pinned it down, look for multiple callbacks responding to the same request and reduce to just one callback.



Iterative v. Declarative Functions

It’s widely accepted that declarative programming is “good” or “better” than imperative programming, but what do the terms even mean? It’s not enough to have a vague idea that declarative programming is easy to reason about - that certainly wasn’t enough for me in trying to understand the difference between the two.

Imperative programming is explained as *how* something is done, whereas a declarative approach deals with *what* is going to be done.

Before we dig further into this, it’s important to realize that declarative approaches are basically an abstraction over an imperative implementation. Think about it - if you’re ordering a drop coffee at a cafe, you can tell the barista “I’d like a pour over coffee”. That’s a declarative approach. If declarative approaches could exist by themselves, the barista would be able to turn to a paper filter and say to it “make a coffee”. That’s not possible. The barista NEEDS to know *how* to make the coffee - that’s the imperative implementation underneath our declarative coffee order. The *what* must be backed by a *how* at some point down the line.

Enough with the fluff - let’s look at some a concrete example in code. In Swift - write an imperative function that accepts an array as a parameter and returns a new array containing all of the previous array elements minus 3.

func subtractThree (fromArray array:Array<Int>) -> Array<Int> {
    var returnArray: [Int] = []
    for item in array {
        returnArray.append(item-3)
    }
    return returnArray
}
  

The above code is difficult to understand at first sight compared to a more declarative approach. We can easily find the operation being performed on each array element because we’re we’ll versed with the general structure of a for loop. However, the code still tells us how we loop over the array instead of directly conveying what we want to achieve.

Loops can be rewritten declaratively by using higher order array functions (map, flatMap, etc). Written declaratively, the above would look like this:

func declarativeSubtractThree(fromArray array: Array<Int>) -> Array<Int> {
    let returnArray = array.map{$0-3}
    return returnArray
}

We’re expressing the logic of an operation without having to describe the control flow involved - this is declarative programming.

 

An Introduction To Node.js

Node.js is nothing but a runtime for Javascript to run outside of the browser - people often think it’s somehow different from pure JS but it isn’t. NPM is the most commonly used package manager to download and install dependencies for projects. js can get pretty low level - there are plenty of modules (http) that make it easy to create an HTTP server and write backend code.

Node.js was designed to make use of asynchronous I/O - many traditional programing languages utilize synchronous I/O. What happens with synchronous code is that when several tasks are being executed on the same thread, one task must complete before control returns to the thread and the next task can be executed. To get past this bottleneck, developers can make use of multiple threads and dispatch certain tasks to certain threads, allowing processes to run concurrently. Managing threads is, to understate it, a challenging task.

Node.js gets rid of the complexities of multithreading by allowing for asynchronous code (see the asynchronous section further down)- functions take callbacks (other functions that are passed as parameter variables) that can make use of the results of the original function. When the original function finishes executing, the callback function is called. 

The thing about writing pure Node.js code is that, in using callbacks that are nested within callbacks, we quickly reach “callback hell” (think pyramid of doom in the context of multiple if/else statements). We can tame our indented code using things like promises or a module such as Async.js. 

Let’s talk about routes - enter Express. Express.js is a lightweight framework built on top of Node.js that leverages the asynchronous event-driven programming paradigms of Node.js and makes it easier to build web applications. As a quick example of how it makes life easier, sending a file in pure Node.JS in an HTTP response object can be quite a few lines of code. After creating a server (or just using the http module “get” or “post” method which creates a server under the hood), we need to specify the response header data (content type, etc), possibly create a data stream out of our file and then pipe it to our response object. In express.js, we’d just use the “sendFile” function. 

Streams and Buffers

What are streams and buffers? In general computer science, a buffer represents a temporary place to house data while it’s being moved from one place to another. Once data has been collected and stored in a buffer, it can be manipulated in some way (read from, written to, etc).  In Node.js , a buffer is a structure that allows for manipulation or reading of binary data - much like an immutable array, a buffer cannot be resized. It allows for much lower level access to data (to the binary data that composes a string vs the encoded value of the string itself, for example). If you use buffers, you gain some performance since you can avoid, in our string example, string management functions.  

A stream represents a sequence of objects (sometimes bytes) that are accessed in sequential order. They’re core to I/O processes (file access, networking, processes). Streams access data in chunks instead of all at once - they’re associated with event emitters so that developers can write callbacks for when certain things have happened involving stream data (encountering an error, receiving data, ending the reading of data). 

In contrast to buffers, streams can read data piecemeal. Buffers need to be processed all at once before any action can be taken to alter the data contained in the buffer. 

HTTP uses a request/response paradigm whereas TCP servers utilize bidirectional streams. We can create readable and writeable streams using the filesystem and then pipe that data into an HTTP response (which itself is a writable stream) or we can pipe an HTTP request (a readable stream) into a data stream. TCP sockets are bidirectional meaning there is an open connection that we can both read and write streams to. 

Asynchronous Code

With asynchronous code in Node.js, we don’t have to deal with multiple threads - that complexity is abstracted away from us within the context of the event loop. Instead, we take advantage of the asynchronous nature of Node.js to write our software. With synchronous code, if we want tasks to run in parallel, they must be executed on separate cores or threads. With asynchronous code, once a process begins, we can begin another one without waiting for the original process to complete. We use callback functions to perform operations with the return data after a process finishes. 

Let’s use reading a file as an example. With asynchronous code, once the file starts being read, we can go do some other task. When the file is finished being read (whenever that may be), our callback function that we wrote earlier handles the results. 

Imagine we were to write a program that did the following - [print message to console] -> [read contents of file asynchronously and print contents to console] -> [print end message to console]. In asynchronous code, we don’t know when the contents of the file will actually finish being read. It may very well turn out that our first print statement and our end print statement get logged, THEN the file contents are logged. If we did this synchronously, the first print statement would be logged, then the program would hang while the file was read and the contents were logged, and we would see our end print statement last.

For this reason, being able to serialize asynchronous tasks is an important part of writing code in Node.js. As a very simple illustration of this concept, say you're writing client side code and you need to get data from several APIs - you have the URLs in an array and you want to execute a GET request for each. If your code is asynchronous, you can't be sure of the order in which the requests will be executed. You can solve this by treating your URL array as a queue structure. Shift the first URL off of the array, execute a get request and add the data to a new array. If there are any URLs left in your array, recursively call the function again, this time shifting the next URL off of the array. When the URL array is empty, do something with the data array which will have each response in the correct order. 

This was just a quick primer on writing some I/O code in Node.js! I'll be including more code as I write a backend for a new mobile app and continue learning more about Node.js and Express.js. 

_____________________________________________________________________________

In using Swift, I've enjoyed messing around with pointers to visualize that Swift foundational structures are pass by value and classes are pass by reference (and to help show the idea of Copy-On-Write). In light of learning new language paradigms, it's important to note that Javascript always passes by value.

Questions & Answers from a Three-Part iOS interview

Part 1 - The Phone Interview

DURATION - 60 MINUTES

Some time ago I had the pleasure of interviewing with a large publishing company headquartered in midtown Manhattan. I got the first interview after an in-house recruiter found me on LinkedIn. She quickly set up a phone interview and I did some basic preparation.

The role wanted a candidate who knew both Objective-C and Swift - I figured there wouldn't be too many Swift questions since the emphasis was on Objective-C. I hadn't touched too much Swift at the time so I threw myself into the "functional" nature of Swift, the use of generics and optionals, and I made sure to write blog posts on things like copy-on-write capabilities of the language. In short - I went somewhat low level and learned about the quirks of the languages and how it differs from Objective-C.

I'm glad I did the above - the phone interview started off with plenty of comparisons between the two languages. What's the difference between Array and NSArray? An array is a struct and thus a value type whereas an NSArray is a class and thus a reference type. The interviewer and I talked about blogs we enjoy reading - when we broached the subject of value v. reference types, I discussed a playground I had written some code in to learn about the differences between the two. I talked about how the code helped me learn about copy-on-write and challenges I faced in trying to embed reference types within a struct. 

I had blogged about some of the issues we talked about and the interviewer took note of that and said he had looked at the code I wrote - I felt pretty good about that. Up until near the end of the phone call we talked about more basic things like using categories and when they're appropriate. The interview finished with us talking about issues that arise when trying to use multiple Managed Object Contexts (I didn't know the answer and he said it was totally fine) and about the Core Data stack in general. We concluded by cracking a few jokes, recommending some reading resources and saying bye. 

Part 2 - The First In-Person Interview

DURATION - 180 MINUTES

I received some good news the next day - they were impressed with my phone interview and wanted to bring me in to the office for a more technical interview. When I arrived, I was nervous as hell. I met with the recruiter I had been in touch with and was sent to wait in a conference room with a whiteboard. The principal engineer came in and greeted me, asked me if I needed anything and told me about how things would proceed. He told me he wanted to talk to me and get to know me a bit and then we'd move onto a technical challenge. He didn't really bother asking me about my background - my training and education didn't seem to matter much. He had read my blog and told me that he liked what he saw but had some questions.

He pulled out a screen print of some of my articles with the code attached - I was a little taken aback but was glad he'd thoroughly reviewed some of my material. He asked why I did things a certain way and asked me if I thought it was the best way - I had force unwrapped a lot of optionals and made some variables optional when they really didn't need to be. I explained that I had quickly written the code to just illustrate a concept and explained how I would go about doing things in a safer way - perhaps using "guard" or "if let" statements to safely optionally bind variables if they're not nil. 

He pulled out a MacBook, fired up Xcode with some boilerplate code already there, asked me if I wanted to write code in Objective-C or Swift (I chose Swift) and described a client problem for me - he took the role of a college professor and I was a developer building a product for him. He told me he wanted to show a list with a number of rows that said the number of the cell (first cell shows 1, second shows 2, etc). He was trying to illustrate the concept of infinite to his students. I asked if it was OK to show a very large number of cells before trying to work towards infinite. He said that was fine, and suggested I try 10,000. I set the numberOfRows to 10,000 and in the cellForRow... I set the cell text to be NSString(indexPath.row+1). Easy.

I told him I couldn't do an infinite number - using Int_MAX for the numberOfRows froze the app. He said that was ok and that he had another problem - he wanted to show his class how quickly numbers can grow in size when put through certain formulas. In this case, he wanted me to use the fibonacci sequence, showing the entire sequence up to an infinite number. HE WAS HOPING I WOULD TALK ABOUT PERFORMANCE IN USING THE FIB SEQUENCE SINCE THE OUTPUT GROWS EXTREMELY QUICKLY (I DIDN'T MENTION IT UNTIL I HIT A BUG). I asked him what the formula was, if he had any design stipulations, etc. He said he just wanted to show the fib number at that point in the sequence. 

I created a model class (he told me that was a good place to start). I called it FibNum and wrote an init function to take an integer and calculate the next fibonacci number recursively. Since this uses multiple stack frames, even when I was going for a high number of rows (somewhere around 5,000) and not an INFINITE number of rows, I blew the stack. This was a blessing in disguise! It allowed me to talk about bug solving and let him see how I went about tracking down issues and fixing them. He asked me the pros and cons of using a recursive solution and then suggested I cache the response of a previous recursive solution and pass it into the function (his words were "cache that sucker" and I ended up tail optimizing the recursive function). He then showed me his solution in both Objective-C and Swift - it was really complex. The Swift solution used a class that conformed to SequenceType and allowed for generics - the Objective-C code was waaaay longer and also included an iterator. He asked me if I thought his solutions were "over-engineering" - my answer was "If you know you'll be applying the same concepts to other problems in the near future, it's not over-engineering; If you're just writing code for this one time solution, I would not do that much work.". He seemed satisfied with my answer.

I was asked to wait for my next interviewer - he walked in and introduced himself. We ended up talking on a personal level for a while (sometimes I can be really talkative when I'm nervous and don't know when to shut up) - turns out we both played soccer on the same fields, were both New York natives, and went to rival specialized high schools. Good start (seriously). He gave me a piece of paper and a pen and described a problem - if given an array and a "sum" integer, return a boolean that says whether or not the array contains two numbers that can add up to the sum parameter. I was dreading this moment, mostly because I didn't expect it for some reason (certainly not with pen and paper). I had no autocomplete to help me out - this wasn't pseudocode, as I was asked to write it with proper Swift syntax. Luckily I was OK on the syntax - definitely wouldn't have compiled if I'd typed it into Xcode, but close enough. LET THIS BE A LESSON TO MAKE SURE YOU KNOW API METHODS FOR FOUNDATIONAL DATA STRUCTURES.

I reasoned out loud that I'd need to iterate through the entire array at least once (worst case) and that the "sum" integer was there for a reason. He told me that there was no extraneous information in the problem - this was good. We were having a back and forth about the problem, possible solutions and pitfalls I could avoid in terms of optimization. First I tried using a nested loop - then I thought about lookup times and knew I'd be doing a lot of checking (for the current element, if we've come across the counterpart before, return TRUE). I know hash tables have constant lookup times, and I mentioned that to him - he encouraged me to use a dictionary and told me I was on the right track. I had an hour to solve the problem, and at this point I was probably 25 minutes in.

I finally figured out the solution after going back and forth - all told it was around 45 minutes (too long in my opinion but I was nervous). He told me I couldn't have optimized it more if I'd tried, that there were a few other solutions that offered the same runtime, and that I did a solid job. I was pumped that I'd solved it, despite how simple it was - writing code in front of an audience is never easy. We talked for another 20 or so minutes - we had a great rapport and it was clear we got along. He showed me some of the stuff he'd been doing for company and asked me if I had any project I wanted to show him. I GOOFED and didn't have anything on my iPhone - I quickly downloaded an app I built from the app store and showed it to him. I told him that even though it was really simple, I faced my fair share of challenges with writing my own caching system (amongst other things). We talked about APIs I used, frameworks and how long it took me to build. I explained how I came up with the idea for the project and how I got started with the designs. We ended it there and shook hands as he went back to his desk to continue with his work. 

Part 3 - Meeting the Team

DURATION - 180 MINUTES

A day went by and I was anxious to hear back - I kept going over where I went wrong in my head and kept thinking about what they'd hold against me. My phone buzzed with an email from the recruiter - they'd chosen me as a final candidate and wanted me to meet the team. I went back in a few days later and headed back up to the engineering floor. I was greeted by the principal engineer and we hung out for a few minutes before I was led to a conference room on the other side of the floor - I was greeted by a Software Engineer, the lead QA automation Engineer and the Scum Master for the team. They went over things that hadn't been asked before - my project experience, team experience, agile experience, background, etc. It was much less fun than the other parts of the interview!

The Software Engineer asked me iOS specific questions (such as the use of delegates) - I told her it was just a design pattern that allowed view controllers to communicate with one another. I also told her they could be used for callbacks. We talked about controller communication patterns - delegates, NSNotificationCenter and KVO. To sum up my answers to her, take a look at the table below -

She didn't probe me too much further on iOS stuff. The meeting was OK - trying to impress three people at once was harder than dealing with people one-on-one. When I was alone with fellow developers, I could get a feel for their personality and either talk more or less, more loudly of softly, bullshit a little more or less, etc. With three people at once, a candidate just can't do that. I got a pretty bad vibe from the QA Engineer but got on well with the other two team members.

The principal met back up with me and asked me to go on a walk with him - we went to the lobby and looked at some of the art on the walls and talked about random things - our childhoods, passions, favorite buildings in New York, things like that. He brought me to other departments in the building (the company owns the entire building) and let me see cool stuff being worked on that wasn't related to Software Engineering. Finally we went to the top floor and sat on plush leather chairs - I was waiting to meet the department head and the director of a partner department. They were finally ready for me - they were both very senior. After the conversation flowed for a while, they figured out that I'd looked them up on LinkedIn and we had a laugh about it - the director looked at the department head and said "He's clearly done his research". We talked about the challenges the company faces, I asked them about difficult situations they've been in - the meeting was mostly for ME to question THEM.

The one question that really stuck with me that they asked was "Are you more of a product guy or a development guy?". Without a hitch I told them I'm a product guy - if I fundamentally disagree with a feature being introduced or something of that nature, I don't care how junior I am, I'm going to bring it up. I think they liked that, but I'll never know because I never heard back from them. I contacted the recruiter several times and never got a response. I called her and left a voicemail - I got an email from her almost immediately saying they went with the other candidate. Unfortunately, I didn't get any feedback. It was down to me and (most likely) one other candidate - whatever the outcome, that was a good feeling. I learned a ton just by talking to so many different, deeply intelligent people.

All told, I spent 7+ hours interviewing with them. I was upset at the outcome, not so much that I didn't get the job as the fact that they never contacted me to tell me the outcome. It was a fantastic learning experience regardless - I hope it my talking about it helps others. Some parts were far more intense than I expected (having the code in my blog looked at for mistakes, for example). Always prepare for a thorough vetting process when it comes to being interviewed. Be prepared for anything and you'll be surprised by nothing. 

Interview Question Practice Series: Pt. 2

Continuing right where we left off:

Question 6

(FB front-end engineering question) Using HTML & CSS, create an image that displays another image when the user hovers over the image. Align the image to the bottom right of the screen. 
You can see the code by clicking here.
  1. This one is very straightforward if you've used a bit of CSS here and there. You need two HTML img elements and need to assign classes to them.
  2. The rest of this just tests your CSS knowledge, mainly the "display" property. You can just set up the display of your first image to be "block" - you can opt to set up other properties to make it look nice, setting a relative position, etc.
  3. After that, you set the bottom and right properties of your second image to be "0" so that it aligns to the bottom right of the screen. Display should be set to "none" so that it's hidden until a user interaction forces the view.
  4. Lastly, we look at the "hover" pseudoclass (simply defines a special state of an element). We specify that we are targeting the hover for the first image and use teh "+" operator to say that we want to overlay the second image.

Question 7

(FB iOS engineering question)This one is the most challenging out of what we've covered so far, in my opinion (mainly because it involves domain framework knowledge and not general programming knowledge). iOS developers have the option to create a dispatch queue that executes an action after a delay (dispatch_after(when, queue, block).It isn't easy to cancel this dispatch queue once it's set up - implement a cancellable_dispatch_after method to allow for easy cancellation of the block.
  1. The first thing to note is what parameters there are in a dispatch_after method. The "when" is a dispatch_time object, the queue is just the queue on which to submit the block, and the block is just that!
  2. If we're delaying a UI action based on a user interaction (pressing a button, perhaps), the queue we're executing on is obviously the main queue. Make sure you're aware of that in case you're ever asked in an interview.
  3. Let's think of a use case for cancelling a block that is being executed after a delay. Say you have an animation that needs to be cancelled if the user touches the screen in the middle of the animation. We could have a boolean value that determines whether or not the screen has been tapped (we can set it to false as a class variable and then in a gesture delegate method we could set it to true). In our cancellable block, if the boolean is true, it means the user has tapped the screen and we can cancel the animation block.

Interview Question Practice Series: Pt. 1

It's been a while since I've posted here - I've been doing functional QA work to pay the bills, but it's time to get back to iOS development topics (I've been keeping my Swift skills sharp and discussing them here helps reinforce everything I learn). This series will cover algorithm challenges and other domain specific knowledge (I've also been covering some front-end stuff, so I'll be including HTML, CSS & JS specific questions here). 

Note that these have been taken from person experience in interviews, glassdoor questions listed by big companies (largely Facebook), and a few are questions I just made up myself as personal challenges. 

Let's look at the questions and cover the answers for each. You can follow along with the code on my github repo.

 

Question 1

(FB FE engineering question) Given a multi-dimensional array, write a function to flatten it ie. Given let arr = [1, "hello", [26, "bye, 3, [5, 29]]];
the output should be: [1, "hello", 26, "bye", 3, 5, 29];
  1. We should start with an empty array that can hold objects of type <Any>.
  2. The next step is to loop through elements in the array using a range for i in 0..<input.count. We can also just use a for element in input loop if we want.
  3. Capture the current element in a variable - we need to check if it's an array or not. If it isn't an array, we can append it to our output array. If it is an array, we need to flatten it again by recursively calling our method.
  4. Feel free to use a ternary operator here for elegance! If data is an array, call our method and make sure to cast the element as a generic array (the function is expecting that as an input). If not, just append to our output array.
  5. Return the array and that's it. My posted code includes a few other methods includes a tail optimized recursive solution and a way to avoid writing loop code (makes use of dropFirst())

  1. For an iterative solution, we need to treat the input array as a stack which we'll perform pops on. We pop the first element off and check it to see if it's an array.
  2. Since we're popping off values from our array and capturing them, we're mutating the array. Items passed in as arguments cannot be mutated, so we need to create a mutable copy of the input array and work with that. Our loop will be a while loop that checks that the value of our mutable array is >= 0.
  3. If the element is an array, leave it as is and append the rest of the mutable array to it. This maintains element order. Set the mutable array to be equal to this new array and the loop will continue.
  4. If the element isn't an array, just append it to our output array.
  5. I foolishly didn't check the Array documentation to look for a "pop" function (you can use array.removeAt(n) to capture an element at a certain index. Instead, I just wrote a "shift()" Array extension function. Use self.first to capture the first element, set the array to be equal to itself.dropFirst() and return the captured first element.

Question 2

(FB iOS engineering question) Recursively and iteratively pairwise swap linked list nodes. If the number of nodes in the list is odd, leave the last node alone. Assume you have to write the code to build out a linked list and node structure. If you start with
var testList = 2->5->9->15->5 then the output should be: 5->2->15->9->5. Change the list in place instead of creating a new list and copying over nodes.
  1. Let's reference the above image. The first thing to think about is how this conceptually works. We need our second node to point to our head node, and our head node to point to the fourth (which will then point to the third). Swapping the first and second nodes is easy - what happens if we do that before grabbing a reference to the third node? The second node.next will point to the first and not the third, and we have lost any pointer to that third node. Therefore, we grab a reference to the third node and call it "temp".
  2. Second.next will point to the head, the head will point to temp.next (fourth node) but now what? We must reassign our nodes with the "node1 pointer" now pointing to our temp node. The same rules apply here - we'll have a node2 pointer that points to node1.next (fourth node in the entire list), and the temp node will point to the fifth node (not pictured).
  3. We can do this iteratively with a while(true) statement. We break when we reach a nil node (end of the list). We assign the variables before the loop, make the swaps within the loop and at the end of the loop reassign the variables.

  1. For a recursive solution, we need a reference to the second node in the list (or the second node in the pair, to be more precise). We can assign it to a variable called newNode (let newNode = listHead.next).
  2. The "swap" operation here involves two things - having the newNode point to the listHead (2->1), and having the listHead point to the rest of the (swapped) list. We must first point the listHead to the rest of a swapped list (which we'll swap recursively) by setting listHead.next equal to a recursive call to our function (this time passing in listHead.next.next as the node). We can then finish by fulfilling the second operation and saying that newNode.next is equal to the listHead.
  3. Remember that newNode is listHead.next so for the first function call, it would be 2, and in the second call, since our listHead is being passed in as 3, newNode would be 4. We're setting listHead.next equal to the function call return value, and 1 (listHead in the first function call) needs to point to 4 (newNode in the second call). Thus, we should finish our function by returning newNode.
  4. That's it!

 

Question 3

(I made this one up) Write an algorithm to create a linked list (using the code written for problem #2) from an array that is passed in (possibly multi-dimensional). You can either include this as an extension method or an init method for your list structure.

  1. As pseudocode, this is easy. Loop through your array and pass each element to your linked list function to create a node and add it to the list. You can even use inputArray.map{pushValueToList($0)} to make use of higher order functions.
  2. This isn't TOO challenging but it does test domain knowledge of protocols in Swift. First of all, we can use the flatten function we created earlier on to make sure that if our input is a multidimensional array, we're handling it properly. We get an error message here if we automatically try and do this that says "Type 'Node' does not conform to protocol 'Sequence'". Once this challenge is tackled, the problem is essentially solved.
  3. In writing out Swift code, this somewhat tests your knowledge of how initializers might work (default and convenience) - we can create a blank init method and a convenience init that takes a generic array as an argument. The convenience init must, of course, call the default init.
  4. We can then loop through the elements in the array and for each one, call our pushValueToList method.

Question 4

Hearst iOS Engineer Interview I was given this in a later interview round with Hearst. Given an array and a "sum" integer, write a function to determine whether two values exist in the array that can add up to the sum. Pay attention to performance.
The final solution is, in my opinion, really elegant. I don't think I'd be able to come up with code like that on a first attempt while writing it in front of somebody evaluating my performance. In fact, I didn't even have to make my code compile because I wrote it out with pen and paper.

  1. This one is fun because it's more straightforward than the others in terms of "algorithmic challenges" (in that it has nothing to do with writing Swift code and dealing with things like generics and unwrapping optionals and conforming to protocols). We also get to focus on performance!
  2. We know that in looking at an array element, we need to determine what other number is needed to reach the sum. This means we're looping through the array at least once (worst case), so we're at O(n) right off the bat. Let's try to make sure performance doesn't get worse than that.
  3. For each element, we want to be able to check if we've already encountered the other partner in the sum pair. If we have, we can break early and return true if our output is a Bool value. Otherwise, we can just return a tuple representing the sum pair.
  4. We know we're looking things up at every iteration of the array, so what data structure do we know has constant lookup time? A hash table! In this case, we're going to use a Swift Dictionary.
  5. Let's think about this conceptually. For each array element we're looking at, we want to see if the counterpart already exists in the dictionary. We need to know what key to look for, as that is what gets hashed and is what gives us constant lookup time. How can we know what to check for at each iteration? We can just check for the sum counterpart!
  6. We can set our key:value pairs to be counterPart:currentElement. That way, for each iteration, we know what key to check because it'll be (sum-currentElement). During each iteration - if let _ = dict[element] {return true}
    else {dict[sum-element]=element}
  7. The problem is deceptively simple - it can take a bit of thought to organize it all but the code is very straightforward. It just tests if you understand how hash tables and their lookup works.
  8. SIDE NOTE: I tried using a ternary operator here to see if I could make the code a one-liner (something along the lines of
    let _ = dict[element] != nil ? return true : dict[sum-element] = element ).
    At one point I thought about trying to use a ternary operator to make the code more concise (if we restructured the code to return a tuple) - it took to long to try and work around and clearly wasn't worth the time spent on it. That's a code smell to me - it would involve forced, inelegant workarounds that wouldn't be clear to somebody looking at it. The ternary expressions are too different to try and link together in such an operator (either returning a tuple or inserting a dictionary entry).
  9. Try modifying the code to return a tuple (sum pair). This shouldn't take more than a minute or two. Good practice, either way!

Question 5

(I made this one up) Using the linked list you designed, implement a simple LRU (least recently used) cache in Swift.

  1. We're not writing any code for this problem. It's too lengthy, in my opinion. I think it would be satisfactory for an interviewer to ask you to just talk about how you would implement an LRU using the linked list you previously wrote (or you could use an array - see number 3 below).
  2. An LRU is essentially set with a capacity and when memory is low, it evicts the least recently used item. We could potentially put this in the AppDelegate didReceiveMemoryWarning() method if we want. The other way it could work is that when we reach cache capacity, if we try to add another item to it, it will add that new item and just evict the least recently used one. Getting and settings values should be done in O(1) time.
  3. If getting and setting needs to be done in O(1), that should immediately make you think of a hashtable (dictionary in this case). We can use a dictionary to look up the address of a value and then access it using a queue. The reason we need a queue is beause order matters here (recently accessed items on the front and oldest at the back) and hash tables cannot handle that. If we want to use an array as the queue, we can just create an array of a certain size and maintain a pointer to the first and last element. You can't beat an array time complexity when it comes to random access - however, if an item in the middle of the array is used, we need to move it to the beginning of the list since it was recently used and shouldn't be evicted. That would involve removing it, adding it, and shifting all the elements after it one to the left. This is memory intensive, whereas with a linked list, we could just drop the node and swap pointers. For that reason, we'll use a doubly linked list.
  4. The hash entries look like "resource identifier: queue node address". When a resource is requested, we check the has to see if it exists. If it does, retrieve it and add it to the beginning of the queue. If it doesn't and the queue has room, create a node and add it to the beginning. If there isn't enough room, delete the last node in the queue, remove it from the hash, make the second to last the tail and add the new node to the beginning.
  5. If we're using this for caching images, we can set the hash key to be the filename and the value to be the new node that contains the file data as the node data.

You can find the second part of the interview series here.

Let | Var | Reference & Value Types

This is about as short a post as it can get! For a deeper look at reference & value types in Swift, see my other post on the topic.

I see a lot of questions on SO that discuss mutability in Swift. Let's go over some basic points about mutable (and immutable) objects in Swift:

  1. Creating a let variable enforces immutability - that variable cannot point to a different piece of data. You cannot change the data at that memory adddress and you also can't point the variable to a different memory address. Say you have let a = 5 and let b = 8.
    You cannot then say a = b nor can you say a = 7.
  2. If you have a var variable, all that means is that your variable can be reassigned - that could mean that the value it points to changes or that you point it to a different memory address.
  3. Structs, enums and other Swift value types (primitives such as Int, Double, String, Array, Dictionary and Set) dispay deep copy semantics. This means that if two variable are pointing to the same memory location, changing the data of one won't change the data of the other. A deep copy of the changed variable will be made and it'll point to its own separate memory address. Each value type instance holds a unique reference to its data. The ability of values to point to the same memory address until they no longer have the same data is due to Swift's Copy-On-Write optimization.
    //Assume Student() is a struct that initializes a student with an age.
    let a = Student(25)
    let b = a
    print(a.age) //25
    print(b.age) //25
    a.age = 35
    print(a.age) //35
    print(b.age) //25
    • As you can see above, changing a property value for a won't cause a change in b. Additionally, both will point to the same memory address until we change a.age - then a deep copy is made, passed to b, and the two variables point to different places in memory
  4. With reference types (often classes) multiple instances can share a single copy of data (they can point to the same memory address). If we pass a class instance to a function, for example, we're actually passing in a reference to the memory address of the object.
    //Assume Student() is a class that initializes a student with an age.
    let a = Student(25)
    let b = a
    print(a.age) //25
    print(b.age) //25
    a.age = 35
    print(a.age) //35
    print(b.age) //35
    • Since we're dealing with reference types, a shallow copy is made, meaning both instances are pointing to the same memory address. A change to data in one will result in change to data in the other.
    • With reference types, it's easy to leave around many reference to an object. Changing data of one reference will change the rest, and this can result in unexpected behavior and leads to bugs. Immutable types are considered safer and can lead to more bug-free code.

Architecture - View and Navigation Logic Abstraction

Views

Aside from pulling out protocol code and putting it into its own file (as covered in my most recent post), we can also pull out view code to reduce the size of our VCs. 

In a typical VC, say we are putting view setup code into our "viewDidLoad" method - we may instantiate several UI components and add them as subviews here. You may choose to create other methods that customize the subclassed UI components when called (which we do from viewDidLoad), ending the customization with adding the component as a subview. This may include using Visual Formatting Language to implement AutoLayout in code. See below:

class BloatedVC: UIViewController {

  private let restaurantName = UILabel()

  private let restaurantImage = UIImageView()

  private let blankSpaceSeparator = UIView()


  override func viewDidLoad() {

  super.viewDidLoad()

  view.addSubview(restaurantName)

  view.addSubview(restaurantImage)

  view.addSubview(blankSpaceSeparator)

  // add a ton of constraint code here, along with other customization including fram  e sizing, color, animations, etc.

  }
}

Here's a thought - instead of putting this code into a VC, why not factor it out into a subclass of UIView? We can have all the same code in that subclass, literally the exact same code, but instead of putting it all in our VC, we just create an instance of that new class in our VC and say

class BloatedVC: UIViewController {

  private var viewObject: ExtractedVCViewCode?

  override func loadView() {
  if let abstractedView = viewObject {
  self.view = abstractedView
    }
  }
}

It's important to note that we set up our view in "loadView", not "viewDidLoad". This is called by a VC when its view is currently nil, so you can instantiate the abstracted view in there.

The code for the abstracted view looks almost identical to the original code we had in "viewDidLoad":

class ExtractedVCViewCode: UIView {

  private let restaurantName = UILabel()
  private let restaurantImage = UIImageView()
  private let blankSpaceSeparator = UIView()

  struct LayoutConstants {
    static let padding: CGFloat = 15.0
    //other constants here for use in autolayout
  }

  override init(frame: CGRect) {
    super.init(frame:frame)
    addSubview(restaurantName)
    addSubview(restaurantImage)
    addSubview(blankSpaceSeparator)

    // add a ton of constraint code here, along with other customization including g     frame sizing, color, animations, etc.
  }

  required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
  }
}

Navigation

Another quick (and to some, perhaps insignificant) way to reduce the amount of code in a VC is by separating out navigation logic - if a cell is clicked, instantiate this VC, pass in this restaurant as the data being provided, and present VC. This won't work for you if you're using IB segues (I prefer writing everything in code for many reasons unless I have a very simple idea I want to quickly prototype). 

First, we have two view controllers - the first displays a list of restaurants, the second displays information for one specific restaurant. We'll leave out typical navigation code, as it will be handled by a third class that neither VC knows about (yay for abstraction). Here's the gist of things - VC #1 declares a protocol with a method that takes a restaurant object as an argument - we also declare a weak var delegate that is of that delegate type. In "didSelectRowAtIndexPath", we invoke that method and say "whoever is implementing our delegate method, go ahead and execute now, here's the restaurant object you'll be needing". That's ALL THE CODE we have for navigation in our first VC.

The third class, that "navigation event handler", is what conforms to the protocol (the code below refers to this class as the "DefaultCoordinator"). This class is what will act as our delegate and actually execute our navigation code. VC #2 doesn't do anything in terms of navigation - it just exists here. The flow of things is VC #1 -> call method in navigation event handler and pass it restaurant object -> navigation event handler creates instance of VC #2, passes restaurant object over to it and pushes it onto the nav stack. Let's check out the code: 

class Restaurant: NSObject {
    var restoName: String
    var restoPic: UIImageView
    
    init (name: String, picture: UIImageView) {
        self.restoName = name
        self.restoPic = picture
        super.init()
    }
}

protocol RestaurantTableViewControllerDelegate:class {
    func RestoTableViewDidSelectRestaurant(restaurant: Restaurant)
}

class RestaurantListVC: UITableViewController {
    weak var navigationDelegate: RestaurantTableViewControllerDelegate?
    private var restaurants = [Restaurant] ()
    
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let selectedResto = restaurants[indexPath.row]
        navigationDelegate?.RestoTableViewDidSelectRestaurant(selectedResto)
    }
}

class DefaultCoordinator: RestaurantTableViewControllerDelegate {
    weak var navigationController: UINavigationController?
    
    func RestoTableViewDidSelectRestaurant(restaurant: Restaurant) {
        let VC = SingleRestaurantVC (restaurant: restaurant)
        navigationController?.pushViewController(VC, animated: true)
    }
}

class SingleRestaurantVC: UITableViewController {
    private var singleRestaurant: Restaurant?
    
    init (restaurant: Restaurant) {
        self.singleRestaurant = restaurant
        super.init(style: .Plain)
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

As you can see, the navigation code for the VC we are navigating away from is minimal. The DefaultCoordinator (which is acting as our navigation event handler) can conform to multiple protocols declared by multiple VCs - all navigation logic can be abstracted away and handled by the DefaultCoordinator. The (potential) downside is that once an app gets very complex with dozens of navigation options, it may be nicer to see the destination VC right there in the "from" VC (instead of tucked away in this coordinating class).

There are so many ways to reduce the amount of code in a VC - it's worth experimenting with. I find that it's easier for me to look at view controllers very conceptually instead of worrying about code involved - this lets me make up a sort of "map" in my head that allows for me to be more free-thinking in my architecture choices.

Architecture - MVC and MVVM

MVC - the typical architectural pattern for many web languages, Objective-C and Swift included. Separation of concerns exist nicely in this pattern - the most immediate problem we have is that Cocoa Touch has bundled our V and C together into a ViewController. Thus, we have view logic and "glue" logic all in one place. Any idea what this may lead to...? That's right! We end up creating a different type of MVC - a massive view controller!

Our views and controllers end up very tightly coupled, and a ton of logic is thrown into our VCs because we can't think of any other good place to put it. MVVM - Model, View, ViewModel, attempts to alleviate this by having a ViewModel act as the new "controller". This lets the ViewController class created by Apple to be JUST a view - no controller logic there. The controller is then truly factored out and acts as a link between the view (which is represented by a ViewController subclass) and our model. This architectural pattern relies on data binding between the view and the ViewModel - that is, when a change is triggered in the ViewModel (based on a change in the model), the changes should cascade down to the view through data binding - KVO, anyone?

This isn't really all that different from TRUE mvc - this is a problem, as far as I'm concerned. All we've done is create a new repository to dump things that we don't know where else to put - instead of putting this logic in a VC alongside view code, we lump it into the viewModel. Yeah, our ViewController classes have less code now and are more focused and testable, but instead of having bloated ViewControllers, we have bloated ViewModels. THIS IS NOT A COMPELLING REASON TO CHANGE ARCHITECTURE PATTERNS - the two good things I can say about MVVM are that 1. You own your ViewModel, whereas you were previously putting a lot of logic into a ViewController (which is created by Apple and not you) and 2. ViewControllers are more testable with this approach. 

What, then, can we do to truly improve our architecture? For one, create as many classes as you need to make sure that each file has single (or minimal) responsibility. Don't have a class called "BicycleVC" - instead, break that down into "BicyclePartsVC", "BicycleMaintenanceVC", etc. You don't even have to break it down into ViewControllers! Your files can just be regular objects that are used within another file, a controller somewhere else. By breaking down your files and naming them appropriately, all the while obsessively making sure that no class has too much responsibility, you greatly improve your architecture. No single class, not even a controller, will be saddled with too much responsibility and thus won't be saddled with too much code. 

ANY OTHER DEVELOPER SHOULD BE ABLE TO LOOK AT YOUR CLASS NAMES AND, WITHOUT LOOKING AT THE SOURCE CODE, DETERMINE WHAT EACH CLASS DOES AND HOW THE "PIECES FIT TOGETHER". 

Lots of data source code in a TableViewController subclass you're using? Factor it out. Lot's of networking code that encompasses multiple services being lobbed into your VC? Factor it out into several smaller classes, and, if it suits you, use a facade class to allow access to those (private, hopefully) internal APIs. When you think about it, a ViewModel is essentially a facade class used to access the model that is powering your software. Focus less on popular patterns and more on modularizing your classes, forcing minimal responsibility onto each class, and compulsively giving your files detailed names. 

The Xcode Build Process (& more)

The Build Process

Today I'm going to write about a few (read: many) things that I've been meaning to get to - I'll touch VERY briefly upon the Xcode build process, blocks & closures, symbolic links using terminal. A followup post will be about Unit Testing in Swift, and I'll possibly tack on an interesting (seemingly simple) coding problem at the end of the second post.

The build process! Xcode has hidden so many internals from us that without setting compiler flags and checking build logs, we really don't know exactly how our Swift or Objective-C code compiles to a machine code executable. Let's start with build logs, since they can be quite telling - the way to do this is to navigate to the "report navigator" tab in your file navigator (just hit Cmd+8). Build your project with cmd+B and then click "build" under project name dropdown. 

Results of displaying a build log in Xcode

Results of displaying a build log in Xcode

It's too much for me to go into what some of the dropdown information means (you can click on any of the build steps and a button to expand the process log should appear) - this is mostly because I just plain don't know. I did some googling around to try and find some reachable material for someone of my level, but it would take me longer than I want to spend on this article figuring out what it all means. With that being said, here are the basic steps of an Xcode build - preprocessing #include and import statements, compilation into assembly (you can view the assembly code by clicking "debug->debug workflow->always show disassembly),  machine code translation into an executable file and then linking executable files together (using the Mach-O linker). Magical, isn't it? There's more information about each step involved, but it does get very low-level; although it would take me a while to fully understand what happens under the hood of a build command, I know it's in my best interest to spend the time familiarizing myself with the process.

Delegates, Blocks & Closures

Imagine the following scenario - you have a tableview in which you need to download images on a background thread, display them if they exist, and if not, display some other placeholder image. You can't run this on the main thread since you'll be guaranteed to provide a horrible user experience - do it on a background thread. Delegation is a possible solution here since we have a one to one form of communication going on (controller to utility class doing the download). I personally think the best use case for delegation is passing data backwards to a parent controller - however, you can also use delegation to break controllers down into smaller modules and avoid large amounts of code in one place. Downloading images a nice example of that - we could also use GCD within the VC code to asynchronously download images. We could have something like:

    -(void) viewDidLoad {

    NSURL *urlForDownload = self.urlArray[objectAtIndexPath: indexPath.row];

    UIImage * cellImageToDisplay = [self downloadImageInBackgroundWithURL: urlForDownload];

    if (cellImageToDisplay) {

        cell.image = cellImageToDisplay;

    }}

    -(UIImage *)downloadImageInBackgroundWithURL:(NSURL *)url { ...a lot of code here...}

Assume that "downloadImageInBackgroundWithURL" returns a UIImage (we do all of the computation and type conversions within that method). This could add more code than we want to see in our ViewController, so we could break it up using delegates. Delegation requires three components: a protocol, a delegate and a delegator. The glue between the delegate and the delegator class is the protocol - both know about the protocol, but the delegator has no knowledge of the delegate. Makes sense, right? If you want something done, you don't care who does it, as long as they're capable of doing it. This is how delegation works - the delegating class has no knowledge of the class doing some kind of work - the way it knows that it is capable is because it implements the PROTOCOL methods.

Class A, a VC, adheres to a certain protocol. It says "ok, I promise to carry out these protocol methods". A model class (Class B), in this case an image downloading utility class, is aware of the protocol (I often declare them in the same class). It also has a weak property (to avoid retain cycles) called "delegate" which it knows will adhere to the protocol method(s). 

Class A imports the header from Class B, which gives it knowledge of the protocol methods and the "imageDownload" method implemented by Class B. It creates an instance of Class B and declares itself as ClassB.delegate, effectively saying that whenever Class B refers to a delegate within a method, that delegate will actually refer to Class A. We can call the "imageDownload" method from Class B and pass it a URL - Class B will then use that URL to download an image, and will call [self.delegate do something with the image we just downloaded]. Remember that self.delegate really means Class A, so now Class A has an image that has been downloaded for it in a totally separate class on a background thread. Delegation allows for some loose coupling, since Class B has no knowledge of Class A but still manages to send it data. If this sounds confusing, just check out the code screenshots below and it'll clear things up. This is a way to use delegates as a callback! 

Our protocol declaration (written in the same file as the delegating class).

Our protocol declaration (written in the same file as the delegating class).

The implementation of our delegating computation. This downloads an image based on what URL was passed to it and sends that data back to its delegate.

The implementation of our delegating computation. This downloads an image based on what URL was passed to it and sends that data back to its delegate.

This is the delegate class code. It implements the protocol method (which is called by Class B when it has finished downloading data). The protocol method is what gets passed the data as a parameter, which can then be used by the delegate (in this case, our ViewController class).

This is the delegate class code. It implements the protocol method (which is called by Class B when it has finished downloading data). The protocol method is what gets passed the data as a parameter, which can then be used by the delegate (in this case, our ViewController class).

This seems like a lot of code to download an image using an NSURLSessionTask - we could have put all of this code into our ViewController class, but that has 2 drawbacks: 1. It makes our controller file much larger and 2. It isn't reusable. By factoring out the image downloading code into a separate class and including a protocol, any other class can conform to this protocol and have images downloaded asynchronously without having to write more code.

Onto blocks and closures - anonymous functions that can be passed around as objects. Known in other languages as lambda functions, blocks have the useful ability to capture variables in the same lexical scope (lexical scope refers to a practice whereby a range of functionality of a variable is set so that it can only be accessed from the code in which it has been defined). Blocks are then, essentially, objects that can carry out some computation or perform some operation (think function or method) while being able to use variables defined outside of the block. can be used in place of delegation, since instead of dealing with a large amount of code that potentially isn't reusable, we can just create a block and define and use it inline. Think of blocks as some object you can use to carry data and throw around. Complete some task, call a block and pass it the data, throw it to a controller (which will call the method to complete said task and implement the block), and use the data that was passed. Ta-da! A perfect way to create cleanly-written callbacks. 

The same task can be accomplished (arguable more elegantly) using blocks! That's right, we've finally arrived at blocks...the syntax can be intimidating (which is often dealt with by using typedef to make them more readable), but worry not - click here for a quick guide to block syntax. Let's look at some code that makes use of blocks and also downloads images asynchronously - the key difference to note between this technique and the delegate approach is that with blocks, we don't need to declare a protocol and implement some separate method that makes use of the data. We can just call the block from wherever we want and use the code right there in the same lexical scope. No extra method, less code, and variables right in front of your face so there's no confusion about what data is being used and where it came from.

 *NOTE - You can refer to "self" within a block; this will result in a memory leak for the simple fact that blocks hold strong references to self parameters used within the block. The way around this is to use a "block variable" - this is declared before the block and simply REDECLARES self as a weak variable. You then use that block variable within the block body. 

If you wanted to use blocks to download images for a tableView, it's important to keep data synchronized so that the tableView cell receives and displays the correct image. You also need to think about caching images, checking for an existing image for that data model instance before downloading it (if it doesn't exist, download it and save it to that model instance. Other things that could be considered include 1. How to save downloaded images to disk as a file and store the file path to the model instance 2. The best way to load images from disk asynchronously 3. Figure out an efficient way to find out whether the image exists on disk so that you know whether to load it or download it 4. Choosing how you want to clear the cache 5. Factoring all of this logic out of a VC. It clearly isn't as simple as calling a download method with a completion handler at the end. 

Here we actually process the data, downloading an image based on a URL passed to the method.

Here we actually process the data, downloading an image based on a URL passed to the method.

We call the block from our VC and use the data contained in it.

We call the block from our VC and use the data contained in it.

As you can see, we require significantly less code when using a block based callback method. We use the build in NSURLSession API to create a task and download the image, and we call our completion handler (which we passed as an argument to our download method) on the main thread. 

The block we created as an argument for our method is able to hold a BOOL and a UIImage as parameters - the block itself doesn't do anything with this data other than carry it around. In our VC is where we invoke the block, gain access to the data it's carrying with it, and do something with that data. Concise, elegant, and you can see exactly what's going on inline!

 

Symlinks

Symbolic links, which we can create at the command line, allow an object to point to a different object in the file system. They're like aliases for whatever you're pointing to - instead of having to type in the file path for SublimeText in order to use it to open a particular file, you can create a symlink for it and have "sublime" point to that executable file path. 

The way to create a symlink is to use the terminal command "ln -s", followed by the original file path, followed by the alias file path. If you had an installed version of SublimeText sitting in your "Downloads" folder, here's how you would set up a symlink so that typing "sublime" at any point in a terminal session (outside of running a server or being in REPL) will open SublimeText:

    $ ln -s~/Downloads/Sublime\ Text\2.app/Contents/SharedSupport/bin/subl /usr/local/bin/sublime

The ln -s command tells the system we're creating a symbolic link. Sublime Text 2 actually has a unix executable file that is hidden in the package contents. We want to point to that by creating an alias (a symlink) in our local user bin directory. The bolded part is where we are doing that - adding "sublime" at the end tells the system that when we type "sublime" in to terminal, we want to access the unix executable file path that comes bundled with Sublime Text 2. 

 

 

 

 

 

Reference and Value Types in Swift

References and Values in Theory

In Swift, a class is considered a reference type, plain and simple. This is similar to Objective-C, where everything that inherits from NSObject is a reference type. Being a reference type means that references share one single copy of data in memory, and they all refer to that same memory address. An issue with this involves the mutability of such an object - if somebody using a reference to Object A in a class changes some mutable values around, and I’m using Object A in a different class and I’m expecting a different value, we have a problem. 

Structs, enums and tuples are all value types in Swift (Objective-C also uses value types in number literals or C structs). If we say that:

let entree = Entree ()

let entree.protein = “Tofu”

let meal = entree

meal.protein = “Chicken”

Then entree.protein should ALSO have a value of “Chicken”. Both entree and meal reference the same object in memory, so changing the value of one changes the other. 

If we redefined the above as a struct, then the it would become a value type, and changing one would NOT change the other. Changing the protein value of meal wouldn’t change the protein value of entree.

It’s important to note that “let” as a constant keyword means different things for value and reference types - for reference types, let means that the reference must remain constant, but the properties are mutable. For value types, let means that the instance must remain constant, meaning that properties are immutable. 

Struct foo { var isReferenceType = False }

Class foo2 {var isReferenceType = True }

let exampleOne = foo ()

let exampleTwo = foo2 ()

// the below code WON’T work, since we are attempting to change the reference of a reference type

exampleTwo = foo

//the below code WILL work, since we are attempting to change a property value for a reference type

exampleTwo.isReferenceType = False

//the below code WON’T work, since we are attempting to change a property value for a value type

exampleOne.isReferenceType = True

 

To sum up, we can’t change the reference of a let constant if it’s a class, but we can change property values of that reference. We also can’t change property values of a let constant if it’s a struct. 


It’s important to note that Swift favors values almost exclusively. If you need to compare two struct instances for equality (assume we’re talking about value equality, not memory equality) then we need to conform to the Equatable protocol (this is something often required with value types). 

extension structName: Equatable { 

    func == (firstArgument: structName, secondArgument: structName) {

        return (firstArgument.value1 == secondArgument.value1) && (firstArgument.value2 == secondArgument.value2)

    }

}

To make data thread-safe, we would need to use a reference type (class) and implement locking. If you need to compare memory (physical) equality, then you should use a reference type. 

References and Values in Practice

Swift makes use of an optimization technique known as Copy-on-Write for value types - if you assign Object B = Object A, Swift will let both share a memory address even though they're value types. Object B will simply contain a reference to Object A. When the value of one changes, a copy is made, and the objects no longer share a memory address. In a cool optimization twist, if you later change one other object to match the other AGAIN, they'll once again share a memory address.

With some low-level Swift programming (of which there are a few resources about online, none of them actually any good), you can prove that copy-on-write exists - HOWEVER, it only seems to work for a few built-in types (such as arrays)! That's because if you want all that optimized goodness that comes from copy-on-write, you've got to implement it yourself for your custom value types. 

To learn about implementing it yourself, and how to build a Swift array from scratch, check out this article by Mike Ash. He runs an incredibly deep and advanced blog on Objective-C and Swift programming, and writes articles all the way down to the compiler level. Most of it is beyond me right now, but it's still good to glance at. 

You mix and match reference and value types all the time - remember that literals are value types, so whenever you have a a class variable that’s a string or a custom struct you created in a different file, your class is a reference type containing value types. This is common, and works out nicely. 

Things get tricky when you have a reference type contained within a value type. 

Let’s get something cleared up that’s related to the protocol-oriented nature of swift - value types should be equatable! This the expected behavior of a value type (as mentioned in a WWDC15 talk); if we have two integers (a value type in swift), don’t we expect to be able to compare their VALUES? I know I do. The same goes for strings, which, as a literal, are also equatable value types. 

Value types need to implement the == operator. The three properties of equality that must be addressed are that the comparison must be reflexive, symmetric and transitive

  1. To be reflexive, we must make sure that “x == x” returns true.
  2. To be symmetric, we must make sure that “x==y” and “y==x” return the same value, whether true or false.
  3. To be transitive, our == operator must make sure that is “a==b” is true, and “b==c” is true, then “a==c” must also be true. 

If your struct contains variables that are already literal value types, then you can declare the equatable function as a global function and simply compare the variables using the == operator. If your struct contains a struct, that nested struct should also conform to the equatable protocol in order to work your way up. It’s also convention to declare protocol adherence as an extension of the Type definition. 

Making reference types equatable is slightly different - it’s entirely case-specific. Say you have a “Person” class (a reference type) - it has a name variable. Two people can have the same name, but be different people. So how you implement whether or not they're equatable is up to you. 

Let’s return to a value type containing a reference type. We can have a struct be mutated very easily if it contains a reference type. There are ways around this, some better than others, which we’ll visit in a moment. Look at the screenshot below - we have two struct instances, one equal to the other (remember copy-on-write here). We change the value of a reference type variables of the first - desired behavior would be that since they’re both value types, changing data in one wouldn’t affect the other. Not so.

We've managed to mutate a struct by changing data in a different struct! This showcases their coupling based on the existence of a reference type in the struct definition.

We've managed to mutate a struct by changing data in a different struct! This showcases their coupling based on the existence of a reference type in the struct definition.

We can prevent this by forcing our Restaurant to use an explicit initializer - this actually creates a copy of the Person being passed in, instead of holding a reference to it. If we do this, and we pass in "managerTest" to be the manager, our Restaurant will use a COPY of the "managerTest" object. You can check the memory addresses and see that they're different. This means that mutating values of the "managerTest" object won't mutate the "manager" property of our Restaurant. Without this initializer, the two share a memory address, so mutating one mutates the other. The flaw in our design is when we act directly on "bestResto.manager.name" - there is nothing preventing this kind of mutation. 

We can mutate struct values here by just acting directly on the struct instance instead of the original reference type we used to create the "Manager".

We can mutate struct values here by just acting directly on the struct instance instead of the original reference type we used to create the "Manager".

The concept at hand here, a far cry from where we came, is data encapsulation. We've covered this in a previous post, but not with the complexity of a reference type contained within a value type. Let's start planning: a good solution would be to create setters and getters for the “manager” property of our Restaurant struct - get simply returns the current value, and set would create a copy of the manager and set the “manager” property to be equal to the new value. This way, if the data is changed, a deep copy of the reference type is created (vs a shallow copy, which creates a new object that simply points to the copied object...aka a referencing object). 

See any problems with this? I do. For one, we're creating a copy every single time the data is written to, instead of just mutating the existing copy. How can we say "If this object is currently referencing another object (shared resource) then make a deep copy with the changes. If nothing else is referencing this, just mutate the existing object instead of making a copy"? In comes "isUniquelyReferencedNonObjC", a method that detects the reference count of an object and returns a boolean value. You pass in the address of an object, it find other references to that object, and if there are no other references, it returns "True". Basically, if this returns "True" for our manager object, it has nothing else referencing it, and we can just mutate the existing copy. This raises a few questions that we'll address in a moment. 

Check out the code below - this is in a project. We have out VC code which creates two structs, the second equal to the first. We check the memory address of the MANAGER (which is a reference type), NOT the struct. We only implemented copy-on-write for the manager here - remember that custom structs don't implement copy-on-write automatically, so if we wanted that, we'd have to implement it ourselves. In this case, we just did it for the Person object. 

The managers share the same memory address - this is what we'd expect. After we change the manager object of the second restaurant object, the memory addresses are suddenly different! Our copy-on-write worked! The "withUnsafePointer" code is how we get the memory address of a struct. This is to prove that our struct doesn't implement copy-on-write (they have different addresses in memory from the very beginning, even though they have equivalent values). The other functions used to obtain memory addresses are just C functions that we're using in our Swift code.  

Memory address console prints to show copy-on-write in action

Memory address console prints to show copy-on-write in action

The last thing I'll add is a screenshot of my code for Restaurant - it changed since the last time we wrote it. The "manager" variable is now private, and we can only change it by using explicit APIs - this is to avoid developers accidentally changing the manager of a restaurant. If they want to change it, they call a clearly defined API that tells them exactly what they're doing so that any confusion is avoided. We get the current manager through a computed property "currentManager" and we implement copy-on-write in our "assignNewManager" function. The function is mutating since, if the manager object is uniquely referenced, we want to change it in place. Else, create a copy of the manager being passed in and assign it to our manager property. 

Encapsulated logic for creating a Restaurant struct

Encapsulated logic for creating a Restaurant struct

There's one more thing to talk about! What if we want to have two restaurants that share the same manager? This is a perfect representation of our situation - Restaurants are unique, and so should be value types. Managers can be the same person, and so CAN be references, but managers with the same name can ALSO be unique, and so CAN be value types (read - structs). Solution - it doesn't work here. We can create a new Restaurant object and pass in the Person we created as the manager, but our init method forces a copy to be made. We need to tinker with our init method and perhaps implement copy-on-write somewhere else in our code.

There are other edge cases to consider where our code WILL NOT WORK. I've been racking my brains for a few days here and there, trying to come up with an elegant solution that works. I'll keep working on it and I'll be sure to post here when I find a good solution.

That’s a ton to cover - we’ve reviewed lazy variables and working with constants, lazy sequences, reference and value types, equatable protocol implementation for value types, and discussed scenarios where you may WANT to have a reference type within a value type and how to write solid, defensive code in that situation. This was a long post, but definitely one of value. 

Being Lazy in Swift

Lazy Variables & Constants in Swift

Say you’re working on some application that has optional features - perhaps you have an image that CAN be resized if a thumbnail is required, but there is a chance that a thumbnail will never be viewed. Image scaling algorithms are computationally taxing - what if our user never ends up accessing a thumbnail? In that case, it doesn’t seem right to demand that a user ALWAYS wait for such an operation to be performed. Remember, allocation is slow, so defer until needed, and memory is limited, so don’t waste it. Use lazy instantiating when the initial value for a property isn’t known until after object initialization, when performing some intense algorithm or perhaps when calculating a large number (like pi to a large number of digits). 

In comes lazy loading - this is a technique used to defer instantiation of a variable or sequence (in swift) until it is actively needed. In swift, if you have a variable in a class that is part of the class’ designated initializer, the value must be computed since the compiler forces that every property within an initializer method be initialized. That may look something like this:

extension UIImage {

    fun resizedTo(size: CGSize) -> UIImage {

        // insert algorithm here    

    }

}

Class UserImage {

    static let smallSize = CGSize(width:36, height: 36)

    var thumbnail: UIImage

    var defaultImage: UIImage

    init (defaultImage: UIImage) {
        self.defaultImage = defaultImage

        self.thumbnail = defaultImage.resizedTo(UserImage.smallSize)

    }

}

What if we never need to use the thumbnail? We just performed an intensive operation for no reason at all - lazy variables take away this problem. In Objc we could leave the thumbnail out of the initializer and do a check for its value by making the thumbnail a computed property with set and get values. In the get, if the value is nil, THEN we would call our resizedTo method; in the set, simply give it a new value. We can immediately set a thumbnail value if we wish to, but if we end up attempting to access it without having initially set a value, it will call our resizing method. Thankfully, lazy instantiation with swift allows us to write less code while still achieving the same result.

The above can be achieved with just a single line of code- 

lazy var thumbnail: UIImage = self.defaultImage.resizedTo(UserImage.smallSize)

If we need to add more lines of code to compute our property, we can just use a closure - 

lazy var thumbnail: UIImage = { 

    let size = CGSize(

        width:min(UserImage.smallSize.width, self.defaultImage.size.width), 

        height: min(UserImage.smallSize.height, self.defaultImage.size.height)

    return self.defaultImage.resizedTo(size) 

} ()

The fact that a property is lazy means the value will only be computed when the entire class has been initialized, so it is safe to reference self within a computed lazy property. 

Note that let constants, if declared at global scope or as a type property (static let) are automatically lazy. Other than that, you can’t make them lazy. An interesting thing to note, as stated by Chris Lattner (designer and project leader of LLVM, Clang and Swift), is that “let” is about physical immutability, not logical immutability. Physical immutability means that once the bits are set in memory (when the let value is initialized), they can’t be changed.

Lazy Sequences in Swift

The SequenceType and CollectionType protocols in Swift have a computed property named lazy - it returns a LazySequence or LazyCollection, depending on which protocol we’re implementing. Lazy applies only to high-order functions in Swift (array.lazy.map(addOneFunction)). This code would only execute for values we actually need; if we printed (array[0], array[10], array[20]) and lazily mapped our function to those values, our program would only make three calculations, one for each value we try to access. If our array has 20,000 elements in it, we can use this to avoid calculating the values of each element after mapping a function to it, and limit our processing to just the values we want.