5 things I learned this week #4

Back from 8 days spent in India for work purposes and it’s that time of the week again:

  • Some new vocabulary for me this week, with the term SRP: Single responsibility principle. This is the concept as per which every module or class should have a single responsibility. Throughout the different tutorials, programs and classes I took about iOS development, this concept was usually taken into consideration but none of the teacher or writer explicitly referred to it – and I think that’s unfortunate. This should be one of the very first topic of any programming language class or program.
  • Digging into the SRP concept explained above, I found this GitHub repository listing Object Oriented Design principles. In addition to SRP, it explains the following principles:
    • the Open Closed principle (extending a class behavior)
    • the Liskov Substitution principle (subclasses must interchangeable with their base class)
    • the Interface Segregation principle (avoid interfaces that clients do not need to use)
    • the Dependency Inversion principle (decoupling modules)

    All of these concepts form the SOLID acronym which represents the five basic principles of object-oriented programming an design.

  • Method swizzling or the ability to modify methods at runtime in order to inject stubs or mocks objects. Part of my learnings on test-driven development, I came across this blog post from Jon Reid on QualityCoding.org. If the name was somewhat scary at first, the concept is fairly simple and even better news: many frameworks are available to help do the job!
  • Swift 3.1 is here and Cosmin Pupaza took the time to write an amazing article about its feature on Raywenderlinch.com. Here is just a quick summary of the language updates as highlighted in the blog post linked previously:
    • Failable numeric conversion initializer
    • New Sequence (protocol) functions: prefix(while:) and drop(while:)
    • Concrete type constraints (previously only protocols could be constraints)
    • Nested generics (and how nested class can inherit T from its outter class)
    • Availability by Swift version (although I’m not quite sure about how useful this feature would be)
    • Convert non escaping closures to escaping ones

    This release also includes updates on the Swift Package Manager, but I have not dug into this topic yet.

  • App size can be a pretty important factor in terms of downloads success, as Apple does not allow the download over cellular networks for apps above 100MB (nothing new but I’m catching up). Such download can only be initiated over WiFi, which could therefore results in a loss of potential users. See the example of Peter Reinhardt who saw a 66% drop of installs after the app gain some weight and went over the 100MB limit.

5 things I learned this week #3

3rd episode in this series that keeps me reading and learning (almost) every day!

  • XCTest teardDown: “Every object you create in setUp should be destroyed in tearDown“. This article from qualitycoding.org explains that if an XCTestCase instance is created for every individual test invocation, it is not automatically destroyed/deallocated upon completion (which one could naturally expect thanks to ARC). Hence why the need of leveraging the tearDown method to deinitialize anything that could impact following tests. Doing so guarantees that each state are evaluated independently (which is part of the testing best practice named FIRST) and start with a clean state.
  • Debugging and crash symbolication: understanding and fixing bugs can be very frustrating, but it is even more if we don’t understand how useful crash symbolication can be. As Dmitry Fink mentions it in his article iOS Crash Symbolication for dummies,

    symbolication is the process of translating the return addresses [in a stack tracet] back into human readable method, filename and line numbers.

    The tutorial explains how to get the dSYM file, which is where Xcode puts all the debug information during the build process, and how to “manually” match it with a crash report. Understanding the logic is extremely useful, but hopefully several tools like these onesare here to automate this process and make our life easier.

  • Swift optimization: writing code that works is fine, but writing performant code that can easily scale up as more and more users use your app is WAY better. This is kind of “old” but this week, I came across this official swift GitHub repository: Writing High Performance Swift Code. Many advices are extremely simple to think about and implement:
    • reducing dynamic dispatch by using final, private or fileprivate appropriately
    • using container type efficiently by adding the value type in an array or doing in place mutation
    • marking protocols as class protocols if they are limited to class only
    • and more that I’m yet to explore and fully understand.

  • Code habits: writing your tests even before you write your production code. This is something completely new to me but I do see the idea here. This concept was introduced to me by Essential Developers in their TDD (Test Driven Development) YouTube series. The two developers, Caoi and Mike, share weekly videos on how they go about building an app from the idea until the full code completion, demonstrating:

    the discipline of test driven development, the power of modular systems, and how to welcome future requirements.

    Each week covers a new topic from storyboard prototyping to testing, swift closures and recursion, retain cycles, or writing a framework.

  • guard vs if let: in her article Natasha the Robot discusses the difference between the two options to safely unwrap values, and when one should chose one vs the other. The conclusion is pretty straight forward, use guard if the value you are looking for MUST be present (and if not you can gracefully exit) and use if let if this value can also be nil (which allows you to continue even without this value).

5 things I learned this week #2

Coming in a bit late due to some travels to New York and then to India over the last couple of days but here we are:

  1. Basic Unit Testing and the use of the XCTest library to assert critical methods from simple projects we had previously built within the University of Washington iOS Certificate. To deepen my understanding of Unit Testing, I have also started the Ray Wenderlich dedicated tutorial which goes further with the use of stubs, mock objects, UI testing and performance testing. A new programming skill from which I just started to scratch the surface!
  2. Better/easier Serialization is coming for Swift, and will provide a way to encode struct and enums and a type safe solution to serialize to external formats like JSON and plist. No more if let dict = json["myDict"], let val = dict["myVal"] or -worst- nested conditional unwrapping. It will also removed the need for dedicated framework such as SwiftyJSON.
  3. Using inout parameters to manipulate external variables (external from the scope of the function). The variables are passed by reference, and therefore sustained any modification applied by the function. See Apple’s documentation for full details.
  4. Using protocols to handle networking calls and subsequent results (with dependency injection) not only make the code more readable but also allows for better testing. Great article from Natacha The Robot!
  5. Method dispatch, 3 primary methods (direct, table, and message) and all of them are supported by Swift. If you ever wondered what’s really behind the static, dynamic, @objc, final, or @inline keywords and about overall code performance, I found this article from Raizlabs extremely well written. It details how Swift handles dispatching for value types, classes, protocols and NSObjects while also highlighting what matters in how we write code (use of extensions or of reference value for instance).

5 things I learned this week #1

I’m starting this series of weekly posts to highlight 5 things I recently learned.
The concept is to explain each new learning in a one liner and to link to the original source or any related resource.

  1. Xcode shortcuts: or how to add or customize keyboards shortcut to never use leave your hands off the keyboard. Credit to the Erica Sadun blog post.
  2. Adding your own custom framework in Swift is not that complicated. See the 9 min YouTube video tutorial of Vea Software.
    A challenge I faced though is that building the framework with “Generic iOS device” seems to prevent the compiler to identify my framework class once imported into a project (even after properly add the embedded binary). Building the framework with a different active scheme solved my problem.
  3. LLDB (Low level debugger) allows one to execute method after hitting a breakpoint. The command is expr (short for expression) followed by the method code.
  4. Swift Generics can have Type Constraints. This is particularly useful when using protocol to make sure that the dynamic type conforms to specific behaviors that you previously defined. Checkout the Raywenderlich tutorial on Generics.
  5. The Lottie library developed by AirBnB is pretty amazing. It enables the integration of beautiful Adobe After Effects animations in iOS app using JSON files or a URL payload. I will try to integrate it in my next project app.

That’s it for this week!

Debugging

Introduction

Swift debugging is a powerful skill that allows developer to quickly identify issues and fix them. Even better, it helps us to better understand our mistakes and therefore to prevent them in the future. Which makes us better programmer in the long run.

Before even jumping into the debugging methods described below, one must always start by reproducing the bug. This is key in order to lead our investigation and chose where we should start looking into the code. This should greatly speed up the issue identification and resolution overall.

Debugging methods

Rubber duck debugging

One trick that served me well numerous times is to explain what I expect my code to do to a rubber duck that I have on my desk. As my duck sucks in programming, I need to go step by step into the intended behavior of my code for it to follow along, and I usually find out what I did wrong when doing so. But in case a bug is not THAT obvious, here are the debugging methods I learned about.

Caveman debugging

The most simple approach to debugging is to use print statements, carefully placed in the code in order to gather additional information on the app’s behavior as well as the values being carried by variables and/or constants.

func myFunction( param: inout String) {
	print("param is: \(param)")
	param = "Superb " + param
	print("param is now: \(param)")
}

This will print out the value of param in the Xcode console before and after we modify it inside the function.

Screen Shot 2017-03-10 at 3.07.44 PM

This works well for simple/basic debugging but it becomes really cumbersome for more complex issues. Nobody wants to write hundreds of print statement just to understand the state of the app at different steps.

Breakpoint debugging

Here comes the breakpoints to the rescue. A breakpoint is some sort of pause button allowing you to interrupt the execution of your app at a specific… point. This is extremely useful to understand if a particular method is properly called for instance, and what is the state of our variables at any given time and to spot exactly where the code is not doing what we expected it to do.

Screen Shot 2017-03-10 at 3.17.24 PM

When our code hits a breakpoint (while the app is running), XCode provides us detailed information about the stack frame we are in and any additional information available. All of this is done by LLDB, Low Level Debugger, which provides both a graphical and a command line interfaces:

  • the graphical interface is what allows us to place and remove breakpoints in the gutter, and is also responsible for displaying the debug area in a readable fashion (left hand side of the screenshot)
  • the command line interface is available in the Console (right hand side of the screenshot) and allows for advanced debugging via LLDB commands. This tool is extremely powerful (you can add breakpoints anywhere in your code for instance, without having to do it manually for each file) and even allows for the execution of methods.

Breakpoints give countless information for debugging but also enable our ability to step over, step into and step out of a function we are currently investigating. No need to place a breakpoint on each line, you can control what you do next after hitting your breakpoint (including resuming code execution obviously).

Visual Debugging

(coming soon)