How I Taught Myself to Code - Week 5

Tim Platt
8 min readSep 1, 2018

--

Current ‘Learning to Code’ Setup

What did I do this week?

I began the same way I’ve begun the last couple of weeks… reading about closures. It’s a construct I’ve been struggling to fully grasp for some time but the penny is finally starting to drop. I also played around with MapKit, completed a couple of HackerRank challenges and started Ray Wenderlich’s Reproducing iOS Controls tutorial.

I’ve got a few ARKit tutorials I’m itching to try but I need a new iPhone so that I can run the augmented reality apps that I’ll build (you can’t run ARKit apps on a simulator as you need access to the camera); hurry along 12th September!

Tutorials

I completed a couple of MapKit tutorials by following Sean Allens Show User’s Location & Permissions and Reverse Geocode to Get Address tutorials. I chose these tutorials because I’ve not experimented with many different views so they allowed me to use new frameworks (MapKit & Core Location) and a new view type (MKMapView).

I’ve simplified a few parts below because I don’t want my weekly blogs to explain what’s already been covered thoroughly in the tutorials I’ve followed.

Reverse geo-coding the co-ordinates of the pin.

There’s actually quite a lot to rendering a map showing the users location. Firstly we need to check if a users location services are active and available CLLocationManager.locationServicesEnabled() and check whether the user has authorised our app to use their location. If the authorisation status is not determined, we can ask the user for permission to use their location and if the user has agreed, we can startTrackingUserLocation().

We then created some methods to centre the map on the users location and to pass the users location to a function that provides a human readable address for the co-ordinates of that location. A users location is defined in terms of longitude and latitude and we use these values to create or receive co-ordinate values from a CLLocation object.

Finally, I fleshed out a function that was triggered when a user moves the map. The logic in the function checks whether the user moved the map by a significant amount and if they did it ‘reverse geocoded’ the longitude and latitude for the centre of the map, which is fancy way of saying “got a human readable address”.

This function was also the first time I’ve consciously used a completion handler in my code (which is written as a trailing closure)! There’s still some stuff I don’t understand i.e. [weak self] or why updating the label goes inside DispatchQueue.main.async{} , but I’ll get to it.

Reading

Guess what I read about? Closures! Again. Specifically, I read about completion handers, which are closures that get passed to a function as an argument and then called when that function is done. So effectively completion handlers ‘do something, when somethings been done’ i.e. update a view once a successful API requests has completed or present an error once an unsuccessful API request has completed (see examples above). I’m actually going to try and explain them briefly below given how much I talk about them😬😬😬.

Firstly, imagine we want to use some method provided by Apple, we can’t see it’s inner workings but let’s suppose it’s a method that does some operations that may take some time:

'SomeBlackboxApple' Class

The reverseGeocodeLocation(_ location: CLLocation, completionHandler: @escaping CLGeocodeCompletionHandler) in the tutorials section is a great example of an Apple method that takes a completion handler and whose inner workings we can’t see.

Now, let’s suppose we are developing an app and when a the user taps the ‘register button, we will create an instance of someBlackboxAppleClass and then call it’s createUser() method, passing in the users email and password.

‘Application’ Class

createUser() is an intensive operation that takes some time and to prevent the interface from freezing while it happens, someBlackboxAppleClass performs the operation in the background. Therefore our app, specifically the method that called createUser(), needs a way to be notified once this background operation completes. To do this the createUser() method can be designed to take a function as a parameter, which its calls when the operation is completed i.e. a completion handler.

'SomeBlackboxApple' Class - Function receives new parameter, which is called after operations complete.

In the above, when all of the time consuming process have completed, the completion handler function is called and is passed whether the operation was a success and a userID (which may be nil if the operation failed).

Let’s call this method in our app again. However, we also need to create the function in our app that we’re going to pass to the createUser() method.

‘Application’ Class - Passes a function we create to the ‘createUser’ method.

Instead of having a completed function, passing that to createUser and then having that be called from createUser once the operations complete, we can just pass it into the createUser function call as a closure. So let’s convert the completed function into a closure by deleting the function name and func keyword and moving the opening brace to the start of the closure:

We convert the function we wrote into a closure.

Then let’s pass the closure in the method call:

As it’s the last parameter being passed to the method, we can write the method call using a trailing closure:

Finally, let’s run the above:

It may seem like a lot, but in your code you‘re much more likely going to use the createrUser() functionality (i.e. Apple methods) as opposed to define them yourself so 99 times out of 100 you’ll only be writing the code in the registerButtonTapped() function. The complete code is below:

Coding Challenges & Puzzles

I completed two HackerRank challenges this week. The first:

Given two strings, determine if they share a common substring. A substring may be as small as one character. For example, the words “a”, “and”, “art” share the common substring 'a'. The words “be” and “cat” do not share a substring.

I had to complete the task by developing the logic within an empty function. I’ve been doing these challenges in Java because I learned quite a lot of fundamentals from the Java for Complete Beginners course I completed in my first week of coding and I figure it keeps me fresh in Java too. My submission is below:

I realised afterwards I could have checked if the .size() of characterSet1 was greater than 0 after doing characterSet1.retainAll(characterSet2), which results in a set containing only elements common in both sets.

The second challenge took me 4 hours, lot’s of Googling. The challenge was:

Two strings are anagrams of each other if the letters of one string can be rearranged to form the other string. Given a string, find the number of pairs of substrings of the string that are anagrams of each other.

When I started this challenge I honestly didn’t have a clue what to do. Fortunately, I saw on a discussion board that a C++ programmer state how he had felt the same, but then he decomposed the challenge into smaller problems and then pseudo coded solutions to each smaller problem before pulling it altogether. This advice really helped me a lot! I often find myself not knowing where to begin with such challenges.

I noticed that a lot of people solve the challenge above in a variety of ways, it was interesting how different people take different approaches to the same problem.

What were the highlights?

  1. Visible Progress. I feel like I’m making steady progress and I see evidence of this i.e. being able to write about closures, being more comfortable reading code or adapting others code. It’s quite easy to become discouraged when learning to code as the learning curve is so steep, which is why I think it’s important to give yourself some kudos because it’s generally a hard slog and it’s easy to feel like you’re getting nowhere.
  2. Interactions With Developers. I’m luck enough to have a few friends who are iOS developers that show an active interest in my development and it honestly gives me a mental boost knowing when experienced developers are giving you a encouragement. Shout out to Alex Trott and @RobRWApp.
  3. Learning Diversity. I completed some HackerRank challengers in Java and had some moments of ‘organic tinkering in Xcode’ and it made me realise that it’s important to make sure your learning is diverse… a mix of tutorials, experimentation, time-boxed challenges etc. The best teams are those with a diversity of people and thought, the same is true of learning approach.

What were the biggest challenges?

  1. Self Motivation. I’m working pretty hard, but I also feel like I could be working harder, or perhaps smarter; improving my capacity to retain information for instance or focusing better . I tend to reply to e-mails, follow rabbit holes reading about new words/constructs that I’ve not covered before etc. I downloaded Forest app, which I’m planning to start using from next week onward.
  2. Quality of Resource Available. I’m still finding there to be a lot of disparity in quality of resource. In general a lot of iOS resources are either quite dated (especially since the continued move to Swift) or gloss over the basics and get technical very quickly. There’s a lot of awesome people producing lot’s of great educational content and I hope I can support that movement soon, but it’s still a bit of a tricky landscape to navigate as a novice.
  3. Knowing Where to Begin. When it comes to the HackerRank challenges it’s often hard to even know what to begin doing or typing (I’ve become somewhat accustomed to watching videos and following along). This is why problem solving skills are held in such high regard in the software engineering field. My recommendation here is to put pen to paper; code is so abstract that sometimes it’s good to doodle a tangible representation of the problem; I do this a lot when I have nested loops or 2D arrays because my brain struggles to conceptualise these without sketching them out. Or even think about the coding problems you have as analogous real life problems; Swift guidelines for instance explain the concept of optionals by using a physical box that may or may not contain items as an example.

Summary

This week I did a mix of things… tutorials, reading, challenges, writing about what I learned etc and I definitely feel like the diversity of learning is a positive. I’ve realised a couple of important things this week:

  1. Have a plan! To maximise your time, go into the week with a lost of tutorials you want to complete and schedule them into your calendar. When I was following Angela Yu’s tutorials, it was very structured and I just popped open my browser and Xcode and got in with coding. You don’t want to waste your ‘working time’ searching around for tutorials and figuring out what to learn next.
  2. I’m starting to feel like I need my own project to work on. Firstly, I feel I need to move away from following tutorials and regurgitating what the tutors tell me to. Secondly, I need something I can’t put down…if I’m working on my own project I’ll have a natural emotional investment in that project and it will incentivise me to problem solve with that much more tenacity.
  3. Have fun, exercise and step away from the keyboard when things get a little frustrating!
Unwinding with a bike ride and Clementine providing moral support/companionship as always.

Don’t give up!
Tim

--

--