Learn Swift and iOS Development
Master iOS development through in-depth tutorials and comprehensive courses on Swift, SwiftUI, UIKit, Core Data, and more.
Master iOS development through in-depth tutorials and comprehensive courses on Swift, SwiftUI, UIKit, Core Data, and more.
6:06
Swift is a type-safe, statically typed language, meaning that each value has a type and the compiler performs type checking at compile time. Your code won't compile if it contains type errors. The benefit is that common bugs are caught early by the compiler. Swift's type system is strict and that also has its drawbacks. It makes the language less dynamic compared to other languages you may be familiar with, such as Ruby and JavaScript.
in Patterns
7:02
The first application I published on the App Store was littered with code smells, bad practices, and anti-patterns. The application worked, but it was a challenge to maintain. Adding features to a large, complex project becomes increasingly difficult if it lacks direction and structure.
in Patterns
9:47
If you are new to Swift, then you may be wondering what a failable initializer is and why you would ever use one. In this episode, I show you how to create a failable initializer and I hope I can convince you of their benefits. I use failable initializers in every project I work on and you may be surprised when I say that you do too.
in Patterns
11:54
The builder pattern isn't a common pattern in Swift and Cocoa development and you don't find it in any of Apple's frameworks. It is one of the Gang of Four design patterns and widely used in Java development.
in Patterns
5:55
The title of this episode is a bit misleading because the Swift programming language has no support for abstract classes. There are a few workarounds, though. In this episode, we take a look at two alternatives to the abstract class pattern in Swift.
in Patterns
7:20
Types need to have a unique name. In Objective-C, naming collisions with other libraries and frameworks are avoided by adding a prefix to a type. That is why we use UIView instead of View and CGRect instead of Rect.
in Patterns
8:21
There are several options for sending messages from a view controller to its coordinator. Up until now we exclusively used closures to notify the coordinator. Another option is delegation and that's the pattern we explore in this episode.
in Patterns
6:32
In the previous episode of Mastering Navigation With Coordinators, we refactored the PhotosViewController class. It now uses the MVVM pattern instead of the MVC pattern. We migrated the project from the MVC-C pattern to the MVVM-C or Model-View-ViewModel-Coordinator pattern.
in Patterns
11:02
Earlier in this series, I mentioned that the coordinator pattern works well with the Model-View-ViewModel pattern. The resulting pattern is commonly referred to as MVVM-C or the Model-View-ViewModel-Coordinator pattern. In this episode, we refactor the PhotosViewController class. It currently uses the Model-View-Controller pattern. We update the implementation of the PhotosViewController class to use the Model-View-ViewModel pattern instead. I won't cover the details of the MVVM pattern in this episode, though. The MVVM pattern is covered in detail in Mastering MVVM With Swift.
in Patterns
10:19
There's a common scenario we haven't covered in this series. How do you use a tab bar controller in combination with coordinators? The coordinator pattern is a flexible design pattern and there are several options for using a tab bar controller in combination with coordinators.
in Patterns
8:27
If you're familiar with Cocoacasts, then you should know that I'm a big proponent of dependency injection. I tend to discourage developers from using the singleton pattern if the goal is creating an object that is easily accessible from anywhere in the project. That's not what the singleton pattern is about. You can learn more about the singleton pattern by reading Are Singletons Bad.
in Patterns
5:35
The Photos project exclusively uses storyboards to design and create view controllers. In this episode, I show you that the coordinator pattern isn't limited to storyboards. You can also use the coordinator pattern if you prefer XIB files over storyboards. If you prefer to use neither, then that's possible too. It doesn't matter how you design and create the view controllers of your project.
in Patterns
11:35
We successfully converted the horizontal purchase flow to a vertical purchase flow in the previous episode. The BuyCoordinator and VerticalBuyCoordinator classes have quite a bit in common. In this episode, we add the ability to the BuyCoordinator class to manage both flows by merging the VerticalBuyCoordinator class into the BuyCoordinator class.
in Patterns
10:57
I hope this series has convinced you of the value of the coordinator pattern. You should have a good understanding of the pattern by now and be able to adopt it in a project. In the remainder of this series, we cover more advanced aspects of the coordinator pattern. In this and the next episodes, we zoom in on horizontal and vertical flows. Let's start by discussing the differences between horizontal and vertical flows.
in Patterns
12:00
At the end of the previous episode, we discovered and resolved a memory issue. When the user completes the purchase flow, the BuyCoordinator instance is deallocated by removing it from the array of child coordinators.
in Patterns
9:38
We refactored the AppCoordinator class in the previous episode. The purchase flow is no longer managed by the AppCoordinator class. We created a child coordinator, the BuyCoordinator class, which is responsible for managing the purchase flow.
in Patterns
10:51
The AppCoordinator class is responsible for navigation. It defines the flow of the application and instantiates the view controllers of the project. View controllers no longer need to worry about navigation, which makes them focused and lightweight. There is a cost to this shift in responsibilities, though. As the project grows, the complexity of the AppCoordinator class increases.
in Patterns
12:36
In the previous episodes, we applied the coordinator pattern to a typical Model-View-Controller application. A coordinator handles navigation and, as a result, simplifies the implementation of the view controllers of the project. View controllers are no longer tightly coupled, which increases their reusability. That brings us to the focus of this episode. What are the benefits and possibilities of reusable, loosely coupled view controllers?
in Patterns
10:26
With the foundation in place, it's time to use the coordinator to navigate between view controllers. Remember that the goal is to put the coordinator in charge of (1) instantiating view controllers and (2) navigating between view controllers. This means that we need to make a few changes.
in Patterns
9:05
If you're familiar with Cocoacasts, then you may know that I'm allergic to string literals randomly scattered in a project. Open AppCoordinator.swift and navigate to the showQuotes() method.
in Patterns
9:19
The previous episode zoomed in on the drawbacks of the UIKit framework. The coordinator pattern can help us work around these limitations. Coordinators are in some ways similar to view models. A coordinator is nothing more than an object that removes a responsibility from a view controller. It is responsible for navigation and defines the flow of the application.
in Patterns
8:11
The UIKit framework makes it trivial to navigate between view controllers. You can perform a segue if you use storyboards or you can programmatically navigate from one view controller to the next. This is convenient, but there's also a cost. If you use the API the UIKit framework offers you to navigate between view controllers, then you have less control and flexibility. This can become a significant problem as your project grows.
in Patterns
8:08
Earlier in this series, I showed you that dependency injection with storyboards isn't complicated once you understand how the various pieces fit together. We haven't covered tab bar controllers in this series and it seems quite a few developers run into problems when working with storyboards and tab bar controllers. It's a bit more complicated, but that complexity disappears once you understand how everything fits together.
in Patterns
7:32
In the early days of the iPhone, many developers shied away from Interface Builder for creating user interfaces. Even though Xcode had been around for years and years, if you wanted your application to be performant, you created your user interfaces in code. The first iPhone wasn't that powerful and you had to squeeze every ounce of performance from it by optimizing how its resources were used.
in Patterns
9:36
Many developers are a bit wary of storyboards and I can understand why that is. It's fine if you're not ready to embrace storyboards in your projects. Let me show you how to adopt dependency injection if you're using XIB files.
in Patterns
8:29
Dependency injection is a pattern that's often overlooked, ignored, or discarded by developers in favor of other patterns, such as the singleton pattern. I've talked and written about dependency injection and Swift quite a bit on Cocoacasts.
in Patterns
6:27
In the previous episode, we explored what the guard statement is, how it differs from the if statement, and when it's appropriate to use it. This episode takes it one step further. I show you several patterns I use on a daily basis that take advantage of the guard statement.
in Patterns
8:17
One of the key differences between junior and more senior developers is how they use the tools they are given. While a junior developer looks for any tool that gets the job done, a more senior developer looks for the tools that can get the job done and selects the most appropriate tool.
in Patterns
9:03
My favorite quote about dependency injection is a quote by James Shore. It summarizes much of the confusion that surrounds dependency injection.
in Patterns
8:20
When I first started dabbling with Cocoa development, I almost immediately came into contact with the singleton pattern. Many Cocoa frameworks, including UIKit and Foundation, use the singleton pattern.
in Patterns
6:45
The singleton pattern is a widely used design pattern in software development. Despite its popularity, it's often considered an anti-pattern. Why is that? In this tutorial, I explain what the singleton pattern entails and how to create singletons in Swift.
in Patterns
The Cocoa frameworks and the Model-View-Controller pattern go hand in hand. A typical iOS application, for example, is composed of models, views, and view controllers.
in Patterns
A typical Swift application is composed of dozens and dozens of objects, working together to make your application tick. To get the job done, these objects need the ability to talk to each other. In this tutorial, we take a look at three common patterns that enable objects to communicate with one another. We also discuss when to use which pattern and, more importantly, when to avoid a particular pattern.
in Patterns
Type safety is a fundamental concept of the Swift programming language and optionals neatly tie into Swift's strict type safety rules. The concept underlying optionals is simple, an optional has a value or it does not.
in Patterns
In yesterday's tutorial, I showed you how to use closures as an alternative to delegate protocols. Closures—or blocks in Objective-C—are incredibly useful and I frequently use them as an alternative to existing design patterns. One such pattern is the target-action pattern.
in Patterns
View controllers are notoriously hard to test. Ironically, the Model-View-Controller pattern forces developers to put a lot of the heart and brains of their applications in view controllers.
in Patterns
In the previous tutorial, we laid the foundation for adopting the Model-View-ViewModel pattern in the profile view controller of Samsara. We already implemented the Time section of the table view. This tutorial continues with the Warm Up and Cool Down sections.
in Patterns
Earlier this week, I wrote about the pros and cons of the Model-View-Controller pattern. In that article, I also made mention of a promising alternative pattern, Model-View-ViewModel.
in Patterns
Model-View-Controller, or MVC for short, is a widely used design pattern for architecting software applications. Cocoa applications are centered around MVC and many of Apple's frameworks are impregnated by the pattern.
in Patterns
The title of this tutorial is a bit misleading because the Swift programming language doesn't support abstract classes. Fortunately, there are workarounds. In this tutorial, we take a look at two alternatives to the abstract class pattern.
in Patterns
Have you ever wondered how tab bar controllers and navigation controllers do their work? Even though it may seem as if UITabBarController and UINavigationController are magical classes, they are nothing more than UIViewController subclasses.
in Patterns
Model-View-Controller, or MVC for short, is a widely used design pattern for architecting software applications. Cocoa applications are centered around MVC and many of Apple's frameworks are impregnated by the pattern.
in Patterns
When talking about object-oriented programming, most of us intuitively think about classes. In Swift, however, things are a bit different. While you can continue to use classes, Swift has a few other tricks up its sleeve that can change the way you think about software development. This is probably the most important shift in mindset when working with Swift, especially if you're coming from a more traditional object-oriented programming language like Ruby or Objective-C.
in Patterns
Many developers cringe when they hear the words dependency injection. It's a difficult pattern and it's not meant for beginners. That's what you are made to believe. The truth is that dependency injection is a fundamental pattern that is very easy to adopt.
in Patterns
To avoid naming collisions with other libraries and frameworks, an Objective-C class needs to have a unique name. That's the reason Apple uses prefixes on Objective-C classes, such as UIView, CGRect, and CALayer. Swift modules make the need for class prefixes obsolete.
in Patterns
In Swift, understanding memory management is essential for your app's performance and to avoid potential pitfalls, such as memory leaks. References are strong by default, but, to avoid retain cycles, you sometimes need to make use of weak references using the weak keyword.
in Patterns