Blog

  • Notifications vs Delegates vs Closures

    When developers first start iOS development, a problem that will arise pretty quickly is “How do I pass data between my objects?”. Fortunately, there are many solutions for you to choose from, but this causes a problem in itself. Which one to choose for your situation? It is important that you pick the correct solution for what you are trying to achieve. Three techniques are Notifications, Delegates and Closures. To demonstrate these in action, I will demonstrate with a small scenario where we have a LoginViewController and an AuthenticationSession. Our LoginViewController will take the users credentials and pass them to the AuthenticationSession, which will respond with the users’ unique identifier. The big question is, how do we get our userIdentifier back to our LoginViewController?

    https://gist.github.com/rtking1993/74c844fa095266f764029ab78f91af20

    Notifications:

    A common and very flexible approach is using Notifications. To use Notifications we would simply have to add an observer to our LoginViewController object that wants to retrieve the userIdentifier and send a notification from the AuthenticationSession.

    https://gist.github.com/rtking1993/af25a8498e1ae347678baff10a623f21

    Now you might be thinking, brilliant I can copy this pattern to solve the problem and I don’t even need to read the other two… BUT WAAAAIT! Using notifications for this situation is the worst of the three options, let me explain why. Notifications were designed to be used in one to many relationships, i.e you can set multiple observers anywhere in your app and when you fire one notification every object observing the notification will react. This makes notifications extremely powerful tools, however, they should always be used sparingly. Medium to large sized apps with many notifications firing for different events are a nightmare to debug and maintain. It is very easy to lose context of what objects are interacting with each other. If two objects have a one to one relationship with each other, as they do in our Login case then it is always the best option to use Delegates or Closures.

    Delegates:

    Delegates are another approach which are a great way of passing data between two loosely coupled objects. Delegates are a lot easier to debug and maintain than notifications. Our LoginViewController simply needs to conform to our AuthenticationSessionDelegate and then will be notified by our AuthenticationSession every time we performLogin.

    https://gist.github.com/rtking1993/a3bec3cc9c1a868bcd5c8482cad5f78e

    Closures:

    Closures are another great option for us to consider in this scenario. Closures require the least amount of boilerplate code and are easy to follow a logical flow. Closures are a very good way of passing data between two objects that have a one to one relationship and only have one flow to handle. Here our LoginViewController waits until AuthenticationSession has finished, inside the completion the userIdentifer is transferred.

    https://gist.github.com/rtking1993/3f85d679e015868db61d19c15149d97b

    Your situation will determine which one of these three techniques you use. All three are useful in different scenarios, so it is important to be comfortable to use each one. In our Login example, I would choose to use a closure. It is a great solution seeing as we are passing data between two objects in a one to one relationship. We also have only one completion option to handle. If we had more options I would consider using delegates instead. Because this is a one to one relationship, I would not choose to use Notifications.

    To sum up, If you are passing data from one object to another, consider using delegates or closures first. However, if neither of those suit your needs, keep notifications open as an option as well.

  • Code Snippet: Creating a custom ImagePickerViewController, like Instagram

    The standard iOS UIImagePickerViewController is a great way for beginners to get started to accessing the camera and photo library. However, it isn’t used by any of the major photo sharing apps, they all have custom ImagePickers. It is possible to create your own ImagePickerViewController and improve the aesthetics of your photo application. It will improve the engagement levels of your app as a well done ImagePickerViewController can be much more user-friendly and painless than the default UIImagePickerViewController. I have created an ImagePicker that you can use.

    Code Snippet:

    The first screen is the custom ImagePicker. The ImagePicker gives the user the ability to select images from their photo album.

    Simulator Screen Shot - iPhone 8 Plus - 2018-04-21 at 23.54.56

    On this screen, there is also a filter button that will take you to a second screen where you can apply filters to the original image.

    Simulator Screen Shot - iPhone 8 Plus - 2018-04-21 at 23.55.14

    The source code for the finished ImagePickerViewController example project is available here:

    https://github.com/rtking1993/RTKImagePickerViewController

     

  • Tutorial: Creating CAShapeLayers using UIBezierPaths

    Icons are essential in iOS development. They can be used to display navigational information throughout your application, many of which will be familiar to the user, such as the search and home icon, as they are similar throughout app design.

    But what is the best way of delivering these icons to your users? We could create image assets, drag them into your project and set a UIImageView image property to that icon. This is simple, easy and painless.

    Another option is to draw your icon using CAShapeLayer. This sounds like more work than the original option, but don’t tune out just yet because I am going to explain to you the advantages of drawing your assets using CAShapeLayers and UIBezierPaths.

    1. Your drawing is going to look crystal clear on any screen, no matter what screen resolution you are working with. You can draw your icon on 1x, 2x or future 5x screens and it will not degrade at all.
    2. If you have to change your icon color to indicate a selected state, this is as easy as one line of code setting the color of the CAShapeLayer.
    3. You are able to make adjustments to the size, line thickness, color and other properties with minimal code change as opposed to creating multiple assets for different sizes.
    4. If you have one image asset, that needs to also have a selected state. You there are two image assets. Each image asset will need to exist in 1x, 2x and 3x resolution. Now you have six image assets. Six image assets which are a variation of one image. This is not efficient and will increase your application bundle size, which means larger downloads every time your user updates your app.

    Hopefully, now I have convinced you that drawing your icons is a good idea, let me now show you how easy it is to do!

    Tutorial:

    We are going to start with a single view application template. Inside the first view controller, we are going to put a UIView and two buttons. The two buttons are going to be used to cycle through our shapes that we will be drawing inside our UIView. Connect the UIView and two buttons up with some outlets and IBActions like I have in the picture below.

    Screen Shot 2018-04-14 at 3.52.32 PM.png

    I always like to deal with degrees instead of radians so I have used a small utils class with a top-level function to help me work in degrees. You can copy it below.

    https://gist.github.com/rtking1993/a2ddbfd6d46d1caa7f82f55d7f715680

    Now we are going to start drawing our shapes, all of our shapes are going to be created using UIBezierPaths. Our UIBezierPaths are going to be instantiated with a CGRect which is going to be the bounds of our UIView. Inside this coordinate space we are going to be manually drawing the lines, points, and arcs of the shapes. This requires a little bit of practice but is very rewarding once you get the hang of it. For now, you can just copy some of the shapes I have created for you.

    https://gist.github.com/rtking1993/c0c7eaab374e1d25a3e2944f370771df

    Now we just have to add the code to our UIViewController to show our UIBezierPaths as CAShapeLayers. Here you can see that we are instantiating an array of CAShapeLayers which is going to contain all of our shapes.

    We have an index which we will be modifying using our two buttons, previous and next. Every time the index changes, our property observer, didSet, on the index will change the current shape being displayed inside our UIView, called shapeView.

    If we wish to modify the stroke color, fill color, stroke width of the icons we can do so inside the shapeCreator helper function.

    https://gist.github.com/rtking1993/36a0686c5d47af88848994fc075ddedd

    When you build and run your project you should see something similar to this screenshot. You should be able to cycle through a selection of four icons. I would encourage you to have a play around with UIBezierPaths to see what icons you can create inside your applications using CAShapeLayers.

    Screen Shot 2018-04-14 at 4.12.49 PM

    The source code for the finished CAShapeLayer example project is available here:

    https://github.com/rtking1993/CAShapeLayers