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:24
A magic number is a number that is used in code without much meaning due to the lack of context. Magic numbers are considered an anti-pattern because they make code harder to read, understand, and maintain. Refactoring code that uses magic numbers is also more risky and can be time-consuming.
in Swift
6:54
You're probably familiar with Swift's nil-coalescing operator. The nil-coalescing operator returns a fallback value if the statement on its left doesn't produce a value. I use it quite often and there is nothing inherently wrong with it. The code smell we discuss in this episode of Code Smells in Swift is the value the statement on the right of the nil-coalescing operator produces, the fallback value.
in Swift
8:10
In the previous episode, you learned about the anatomy of property wrappers. Property wrappers aim to reduce code duplication and improve the readability of the code you write. They also implicitly document the code when implemented and applied correctly. That is an added bonus. In this episode, we explore a few additional features of property wrappers.
in Swift
8:19
Property wrappers were introduced in Swift 5.1 to eliminate boilerplate code, facilitate code reuse, and enable more expressive APIs. You may have noticed that SwiftUI and Combine make heavy use of property wrappers. Property wrappers are completely optional. You can write Swift without property wrappers. But once you become familiar with their benefits and understand how they work, you will understand why the Swift community is so excited about this addition to the language.
in Swift
10:02
In the previous episodes, we added support for a vertical purchase flow. Most applications are a puzzle of horizontal and vertical flows. Combining horizontal and vertical flows allows for flexible and dynamic application flows.
in Swift
14:39
The underlying idea of a dispatch semaphore isn't difficult to understand. Remember that a semaphore is nothing more than a variable that can be incremented and decremented in a thread safe manner. The most challenging aspect of a dispatch semaphore is correctly using it. Working in a multithreaded environment is complex. Semaphores help you manage that complexity.
in Swift
14:50
Dispatch groups are a bit more advanced, but I hope the previous episodes have shown that they can be incredibly useful to manage complex tasks. The DispatchSemaphore class is another more advanced member of Apple's concurrency library. While there are some similarities between dispatch semaphores and dispatch groups, dispatch semaphores are more powerful and more versatile.
in Swift
8:42
Most developers don't use dispatch groups on a daily basis. They have a limited use, but I want to show you in this episode that the DispatchGroup class can greatly simplify the code you write when used correctly.
in Swift
10:11
Apple's concurrency library is sparsely documented and that discourages developers from using the more advanced APIs of Grand Central Dispatch. This episode focuses on one of those more advanced APIs, dispatch groups.
in Swift
12:30
Quality of service classes are an integral component of Grand Central Dispatch. You know from the previous episode what they are and how to use them. In this episode, you learn how to efficiently apply quality of service classes.
in Swift
14:27
In the introduction of this series, I mentioned that Grand Central Dispatch operates at the system level. It has an overview of the processes running on the system and the resources that are available. When your application submits a block of work to a dispatch queue, it's up to Grand Central Dispatch to decide when that block of work is executed.
in Swift
14:11
The previous episodes have illustrated that working with the DispatchWorkItem class is a bit more complex than submitting a block of work to a dispatch queue. But you get several benefits in return. Control and flexibility are the most important advantages of the DispatchWorkItem class. In this episode, I'd like to show you a few additional benefits if you choose to work with dispatch work items.
in Swift
11:29
We ended the previous episode with some bad news. We discovered that the current implementation of the ImageTableViewCell class is leaking DispatchWorkItem instances. Before we implement a solution, I have more bad news. The problem is more complex than it appears. There are several memory issues we need to address. Let's tackle them one by one.
in Swift
12:43
You already learned quite a bit about Grand Central Dispatch in this series. Most developers stop once they have a good grasp of the fundamentals. That's unfortunate because Grand Central Dispatch offers a number of more advanced APIs that add even more power to Apple's concurrency library. This episode focuses on dispatch work items.
in Swift
10:18
Up until now we submitted blocks of work to a dispatch queue by invoking the async(execute:) method. In this episode, we explore how Grand Central Dispatch handles the execution of a block of work. Work can be executed synchronously or asynchronously. What does that mean? What is the difference? And what are the risks?
in Swift
7:48
In the previous episodes, we used dependency injection to easily replace objects with mock objects when the unit tests are executed. It's a solution that works fine and it can be applied in a wide range of scenarios.
in Swift
13:16
We're currently only unit testing the happy path. In this episode, we expand the test suite and I show you how to simulate failures. It isn't easy to accurately test failures in the real world and that emphasizes the importance of a robust test suite. Let me show you what I have in mind.
in Swift
4:00
The interface of the RootViewModel class shows that we only need to unit test the initializer and the refresh() method. I explained earlier why I don't unit test the initializer and, in the previous episodes, we unit tested the refresh() method. Does that mean that the test suite now completely covers the RootViewModel class? The answer is no. This is a common mistake developers make. In this episode, we collect code coverage data to expose the gaps in the test suite.
in Swift
8:28
We wrote the first unit test for the RootViewModel class in the previous episode. It's true that unit testing asynchronous code is more complex than unit testing synchronous code, but I hope that the previous episode has shown that it isn't that hard.
in Swift
6:40
Developers that are new to unit testing often wonder what they should unit test. Unit testing is a type of black-box testing, which means that you don't care how the entity under test does what it does. From the moment you start writing unit tests, you need to stop being a developer and take on the mindset of a tester. What do I mean by that?
in Swift
10:49
Earlier in this series, we wrote unit tests for the DayViewModel, the WeekViewModel, and the WeekDayViewModel structs. Writing those unit tests was fairly straightforward. Unit testing the RootViewModel class is a bit more challenging for a number of reasons. The RootViewModel class asynchronously fetches the location of the device and weather data for a location. To unit test asynchronous operations, we need to take a different approach.
in Swift
9:04
The application we worked with in the previous episodes creates and manages a serial dispatch queue and a concurrent dispatch queue. Creating a dispatch queue manually is fine, but it isn't always necessary. Grand Central Dispatch manages a handful of dispatch queues your application can use. The main dispatch queue is one of these dispatch queues. In this episode, we find out which dispatch queues Grand Central Dispatch provides and when you should consider using them.
in Swift
11:12
You should now have a fundamental understanding of dispatch queues. A dispatch queue is responsible for managing the execution of blocks of work. Grand Central Dispatch determines which thread is used for the execution of a block of work. Developers unfamiliar with Grand Central Dispatch wrongly assume that a dispatch queue is tied to a particular thread. Remember that Grand Central Dispatch doesn't make a guarantee as to which thread is used for the execution of a block of work submitted to a dispatch queue.
in Swift
10:22
Dispatch queues are an integral part of Grand Central Dispatch. In this episode, we cover the fundamentals of dispatch queues. Let's start with an example.
in Swift
9:40
I'd like to give the user the ability to manually refresh the weather data. While this isn't strictly necessary since the application refreshes the weather data every time the application is opened, it gives me the opportunity to show you how to implement pull to refresh, a common design pattern in mobile applications.
in Swift
8:48
The application fetches the location of the device on launch and it subsequently asks the Dark Sky API for weather data for that location. That's fine, but it isn't sufficient. What happens if the user backgrounds the application and opens it several hours later. The weather data may be out of date and, if they're traveling, the location of the device may have changed.
in Swift
9:30
It takes time to become familiar with a new programming language and some features don't always immediately make sense. Enums are a joy to work with in Swift, but it took some time before I found a use for associated values. In this episode, we refactor Rainstorm by taking advantage of enums with associated values. We remove unnecessary optionals and make the code we write more readable.
in Swift
14:47
In the previous episode, we asked the Core Location framework for the location of the device and used that location to fetch weather data. That change has made the application much more useful. At the end of the episode, I mentioned that the current implementation introduces a subtle problem. The RootViewModel class is responsible for fetching the location of the device, using the Core Location framework. The implementation of the RootViewModel class depends on the Core Location framework. Because Core Location is a framework we don't control, it impacts the testability of the RootViewModel class. Remember what I said earlier in this series. To write a fast and reliable test suite, you need to be in control of the environment the test suite runs in. In this episode, we use protocol-oriented programming to decouple the RootViewModel class from the the Core Location framework. We used protocol-oriented programming earlier in this series to add a layer of abstraction. It's a powerful pattern that is easy to adopt.
in Swift
13:32
The application we're building is shaping up nicely. It's time to make it a little bit more functional. The application is currently only capable of fetching weather data for a predefined set of coordinates. This severely limits the appeal of the application. In this episode, we use the Core Location framework to fetch the location of the device. The application will use that information to show the user weather data for their current location. That will make the application much more useful.
in Swift
7:10
This episode should look and feel familiar if you've watched the previous episodes because we are about to write unit tests for the WeekViewModel and WeekDayViewModel structs. Let's start with the WeekViewModel struct.
in Swift
12:37
In this episode, we populate the week view. We build the user interface and implement the WeekViewModel struct and the WeekViewController class. Let's start with the user interface.
in Swift
12:57
Because a view model isn't or shouldn't be coupled to the user interface, it's easy to write unit tests for a view model. I'd like to illustrate that in this episode by writing a handful of unit tests for the DayViewModel struct. If you're new to unit testing, then this episode is an excellent start.
in Swift
15:55
Everything's in place to populate the day view controller. Open DayViewModel.swift. Press the Option key and select DayViewController.swift to open it in the Assistant Editor on the right. Implementing the DayViewModel struct is surprisingly straightforward. We first need to inspect the DayViewController class and figure out what type of data the view model needs to provide to populate its user interface.
in Swift
6:45
The user interface of the day view controller is ready to be populated with weather data. Before we populate the user interface, I'd like to clean up the implementation of the DayViewController class. As I mentioned earlier in this series, object literals are very often an opportunity for improvement. In this episode, I show you how we can improve the implementation of the DayViewController class.
in Swift
12:52
It's time to create the user interface of the day view controller, the topmost child view controller of the root view controller. In this series, I show you several techniques for building user interfaces. Each of these techniques has its pros and cons. To create the user interface of the DayViewController class, we take advantage of Auto Layout and storyboards. This approach is ideal for building static user interfaces.
in Swift
7:33
Before we can populate the day and week view controllers, we need to create a view model for each view controller. The view models transform the weather data into values the view controllers can present to the user. This is straightforward if you've watched the previous episodes. There are a few details that are worth pointing out, though.
in Swift
14:11
At the end of the previous episode, I mentioned that I'm not quite happy yet with the implementation of the RootViewModel class. It passes an instance of the DarkSkyResponse struct to the RootViewController class via a completion handler. The RootViewController class still knows too much about the weather data and its origin.
in Swift
14:28
In the previous episode, we parsed the JSON response of the Dark Sky API. It's time to integrate the DarkSkyResponse struct into the Rainstorm project. Remember that we didn't handle any errors in the playground. That's also something we tackle in this episode.
in Swift
13:56
In the early days of Swift, working with JSON was clunky and inelegant. Most developers relied on third party libraries that simplified this tedious task. The Swift team was aware of this gap in the Swift standard library and, after focusing on the foundation of the language first, they introduced the Codable protocol in Swift 4. The Codable protocol is a powerful solution that makes working with JSON quick, easy, and intuitive.
in Swift
13:09
The root view controller is currently in charge of fetching weather data from the Dark Sky API. Having a view controller that performs network requests isn't uncommon if the project adopts the Model-View-Controller pattern. The current implementation of the RootViewController class isn't complicated, but that can change as the project grows and evolves. It can eventually lead to a fat and overweight view controller. That's something we absolutely want to avoid.
in Swift
7:54
Project hygiene is very important in my opinion and it immediately shows you what type of developer you're working with. The Xcode theme I usually use for development highlights string literals in bright red, showing me when a string literal has made its way into the codebase.
in Swift
5:59
In the previous episode, we laid the foundation of Rainstorm's user interface. Before we continue building the user interface, I'd like to know what the weather data the application will use to populate its user interface looks like. In this episode, we fetch weather data from Dark Sky. The Dark Sky API is very easy to use. Create a Dark Sky developer account if you'd like to follow along. It's free and it only takes a minute.
in Swift
12:08
View controller containment is an indispensable pattern in iOS projects. Several key components of the UIKit framework take advantage of view controller containment, including the UINavigationController class, the UITabBarController class, and the UISplitViewController class. As I mentioned earlier in this series, view controller containment is a pattern I adopt in every iOS project and Rainstorm is no exception.
in Swift
7:15
Few things are more enjoyable than setting up a brand new project. Fire up Xcode and choose New > Project from Xcode's File menu. Select the Single View App template from the iOS section and click Next.
in Swift
3:30
In Mastering MVVM With Swift, we refactor a weather application, Cloudy, built with MVC to use MVVM instead. One of the most common questions I receive is how to build Cloudy from scratch. This series is an answer to that question. We build a weather application that is inspired by Cloudy. The application is aptly named Rainstorm.
in Swift
6:47
In today's episode, I'd like to show you an elegant example of the power and versatility of generics and protocols. I came across this implementation while browsing the RxDataSources repository a few months ago. I learned the technique I outline in this episode from Segii Shulga. Let me show you what it looks like.
in Swift
7:39
Control flow is an essential aspect of any programming language. In this and the next episode, we discuss loops and conditionals. We start with conditionals.
in Swift
6:29
Earlier in this series, we covered arrays, sets, and dictionaries. Collections are ideal for storing objects of the same type. Remember that Swift is very strict about type safety. That's why you're not allowed to store a string in an array of integers.
in Swift
8:53
Optionals are an integral aspect of Swift development. They highlight a core concept of the Swift language. Safety. At first glance, optionals look inconvenient and a necessary evil of Swift development. That's true if safety isn't high on your list of priorities. Unless you embrace optionals and what they represent, working with Swift will be a struggle and it will end in frustration.
in Swift
4:41
One of Swift's core features is safety and optionals tie neatly into that mindset. Developers new to Swift tend to struggle with optionals. Optionals are often seen as a hindrance instead of a powerful concept of the Swift language. A common question developers have when they learn about optionals is "Why?" In this episode of Swift Fundamentals, we take a close look at optionals. Let's start with the obvious question "What is an optional?"
in Swift
3:28
Another important collection type defined by the Swift standard library is the dictionary type. Dictionaries are better known as maps, hashes, or associative arrays in other programming languages. The idea is similar, though.
in Swift
8:08
In the previous episode, we explored some of the common types defined by the Swift standard library. Today, we continue that exploration by taking a close look at collection types. The Swift standard library defines three collection types, arrays, sets, and dictionaries. This episode zooms in on arrays and sets.
in Swift
5:38
In the previous episode of Swift Fundamentals, we briefly talked about variables and constants. You learned that the var keyword declares a variable and the let keyword declares a constant. Variables and constants both store values that can be referenced by a name.
in Swift
4:22
Swift is an easy language to get started with. The syntax is easy to understand and reminiscent of other popular programming languages you may already be familiar with. In Swift Fundamentals, you learn the fundamentals of the Swift programming language.
in Swift
A few years ago, Apple's Swift team posted an interesting article titled Increasing Performance by Reducing Dynamic Dispatch. It is a very interesting read, highlighting some of the more subtle aspects of the Swift language and the compiler.
in Swift
Object literals are very useful and they often make your code easier to read and understand. String literals are a bit different, though. It is true that a string literal is the easiest solution to create a String object. It is straightforward and everyone understands what is going on. But there is a price you pay every time you use a string literal. Did you know that?
in Swift
Fatal errors have a negative connotation and with reason. You should use them sparingly if you want to avoid having your application crash and burn at the slightest hiccup. Despite their negative undertone, fatal errors are an integral part of my workflow as I write elsewhere in this book.
in Swift
In the previous tutorial, we implemented two solutions to parse the JSON data we receive from the Dark Sky API using Swift 3. The solutions we implemented work, but they are far from perfect.
in Swift
In the previous tutorial of this series, we fetched weather data from the Dark Sky API. Before we can feed the weather data to the user interface of the application, we need to pour it into model objects. Swift's strict type safety rules make this less trivial than it sounds.
in Swift
We built a basic user interface in the previous tutorial and it is now time to fetch weather data that we can show to the user. As I mentioned earlier, the application we are building uses the Dark Sky API to fetch data for a particular location.
in Swift
In the first installment of this series, we created the project in Xcode, updated the project's structure, and put it under source control. This lesson focuses on building the basic user interface of the application.
in Swift
In this series, you learn how to build a weather application for iOS with Swift 3. Along the way, you learn several skills that are essential for iOS development.
in Swift
Many developers new to Swift seem to be struggling with JSON. Despite the speed of Foundation's JSONSerialization class, it hands you an object of type Any, leaving it up to you to unwrap the object you received.
in Swift
Last year, I wrote about the difference between private and fileprivate in Swift 3. With the impending release of Swift 4, it's time for an update. Access control underwent several important changes since the introduction of the Swift language, several years ago.
in Swift
Last week, I wrote about weak and strong outlets. But there's another question about outlets that comes up frequently. Should outlets be declared as optionals or implicitly unwrapped optionals? This tutorial zooms in on the pros and cons of each of these options.
in Swift
Earlier this week, I showed you how easy it is to work with bitmasks using Swift and the Swift standard library. In today's episode, I show you how to create a custom control that uses the Schedule structure we created earlier. This is what the result will look like when we are finished.
in Swift
A surprising number of developers struggle with bitmasks and bitwise operations. If you've had problems working with bitmasks, then I have good news for you. Swift's standard library makes this easy. In this episode, I walk you through an example I worked on last week for an application I'm working on.
in Swift
At first glance, the collection types defined by the Swift standard library look similar to the ones you find in other programming languages. But if you dig a little deeper, you start to see the differences.
in Swift
Swift 3 brought many new features and enhancements to the language. It also introduced several changes to access control by adding two new access levels, open and fileprivate. I already discussed the difference between private and fileprivate earlier this year. In this tutorial, I focus on the difference between public and open.
in Swift
What do you do if you want to declare a property internal, public, or open, but you don't want anyone but the instance to set the property? You could solve this problem declaring the property private and defining a computed property that acts as a getter for the private property.
in Swift
No day go by without me learning something new about Swift and that is probably one of the aspects I enjoy most about the language. Like most developers, I like exploring new technologies.
in Swift
Automatic Reference Counting, or ARC for short, was introduced in Objective-C several years ago. It greatly simplifies memory management in Swift and Objective-C. Automatic Reference Counting usually works without you having to do anything. But there are scenarios in which ARC needs a little bit of help.
in Swift
If you have already made the jump to Swift 3, you have probably noticed that the API of several libraries and frameworks has changed ... a lot. The API of Grand Central Dispatch, for example, underwent a dramatic makeover. Using Grand Central Dispatch in Swift 3 is elegant, concise, and more intuitive.
in Swift
You probably know that the Swift language defines a number of attributes, such as objc, escaping, and available. It also defines a range of declaration modifiers.
in Swift
A few months ago, I stumbled upon a discussion in the thoughtbot guides about the use of fatal errors in Swift. It seems every developer has an opinion about fatal errors and a consensus hasn't been reached yet in the Swift community. The only mention in The Swift Programming Language is in the section that discusses the guard statement and early exit.
in Swift
When should you use implicitly unwrapped optionals? The short answer to this question is "Never." But the answer is more nuanced than that. Implicitly unwrapped optionals were added to the Swift language for a reason.
in Swift
Developers new to Swift are often confused by the seemingly random sprinkling of question and exclamation marks in Swift code. Yesterday, we discussed the meaning of the question mark. Today, I would like to zoom in on the meaning of the exclamation mark in Swift.
in Swift
Even though Swift is easy to get started with, developers new to the language need to learn several brand new concepts. The most common hurdle developers run into is understanding optionals. What are they? And how should you deal with optionals?
in Swift
Even though you may not know what an autoclosure is, I bet you have already used autoclosures without knowing it. Last week, we looked at the fatalError(_:file:line:) function. What I didn't show you is the function declaration. This is what it looks like in Swift 3.
in Swift
Even though the signature of the fatalError(_:file:line) function looks a bit daunting, it is surprisingly easy to use. In this tutorial, I show you how to use fatal errors and, more important, why you'd want to use fatal errors.
in Swift
It is easy to get started with Swift and that is exactly one of the compelling aspects of the language. But as you use the language more often, you gradually come into contact with Swift's more complex constructs.
in Swift
Developers making the switch from Objective-C to Swift tend to translate Objective-C into Swift. They take what they know about Cocoa development and apply it to Swift. Unfortunately, this often results in frustration and sometimes even an aversion towards Apple's new programming language.
in Swift
The most common question asked by developers new to Cocoa development is about the language they should learn, Swift or Objective-C. The question is simple. The answer is not.
in Swift
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 are coming from a more traditional object-oriented programming language like Ruby or Objective-C.
in Swift
Swift includes a number of features Objective-C developers have wanted for years. Availability checking is one of those features.
in Swift
When access levels were first introduced in Swift, there was some confusion and criticism about them. While developers were excited about the addition of access control to the Swift programming language, the behavior of the private keyword was different from that of other programming languages.
in Swift
Swift modules makes the need for class prefixes obsolete. In Objective-C, it is a best practice to use a class prefix to avoid naming collisions with other libraries and frameworks, including Apple's.
in Swift
A few weeks ago, I wrote about Unbox, a lightweight library to convert JSON data to model objects. There is a lot to like about Unbox and it takes seconds to start using it in a project.
in Swift
Even though most operators in Swift look and behave the same way they do in other programming languages, there are a few you may not know about or that behave in a slightly different manner.
in Swift
Swift is a powerful, expressive programming language with a flexible, elegant syntax. One of the features I appreciate most is its native support for error handling. In this post, you learn about throwing functions and how try, try?, and try! are different.
in Swift
Even though Swift may be reminiscent of several other programming languages, such as Ruby, Java, and JavaScript, it is dangerous to compare it with other languages. In this article, I answer five common questions about the Swift programming language.
in Swift
A lot has changed with the release of Swift 3. The good news is that Swift got better by a lot. The not so good news is that some of your Swift 2 code needs some tweaking. In this post, I show you an example of the type of errors you can expect and how easy it is to fix them.
in Swift
In this post, I'd like to answer a few common questions developers have about Swift Package Manager (often abbreviated as SPM or SwiftPM)
in Swift
In this episode of Swift Fundamentals, we look at string interpolation in Swift. You learn about the syntax, and we look at the benefits and drawbacks of string interpolation in your code.
in Swift
The difference between arguments and parameters isn't difficult to understand. Most developers use the term argument and parameter interchangeably because they assume they are the same or they are not sure what the difference is. Let's take a moment to understand what sets arguments apart from parameters in Swift.
in Swift
Have you ever wondered what version of Swift you are using in the project you're working on? The answer is less straightforward that you might think. This episode of Swift Fundamentals sheds some light on this seemingly simple question.
in Swift
An array in Swift can contain any type of data, values types as well as reference types. The type of data an array stores can sometimes be quite complex, though. In this episode, I show you how to store dictionaries in an array and I show you why an array of dictionaries is usually not what you need or even want.
in Swift
Developers new to Swift are often confused by the programming language. In this post, I answer a handful of common questions about Swift for people new to Apple's programming language.
in Swift
The ampersand indicates that the subscriptions variable is passed to the store(in:) method as an in-out parameter. What are in-out parameters? That is the focus of this episode.
in Swift